tweb/public/297.1bdbe4d3952a46b0e184.ch...

1 line
4.6 MiB
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"version":3,"file":"297.1bdbe4d3952a46b0e184.chunk.js","mappings":"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,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,mBAAmB,MAAO,kBAAkB,MAAO,QAAQ,MAAO,kBAAkB,MAAO,4CAA4C,MAAO,4CAA4C,MAAO,4CAA4C,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,mBAAmB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,mBAAmB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,8BAA8B,KAAM,mBAAmB,KAAM,8BAA8B,KAAM,8BAA8B,KAAM,mBAAmB,KAAM,8BAA8B,KAAM,yCAAyC,KAAM,8BAA8B,KAAM,yCAAyC,KAAM,yCAAyC,KAAM,8BAA8B,KAAM,yCAAyC,KAAM,8BAA8B,KAAM,yCAAyC,KAAM,yCAAyC,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,6BAA6B,KAAM,wCAAwC,KAAM,QAAQ,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,8BAA8B,KAAM,mBAAmB,KAAM,8BAA8B,KAAM,8BAA8B,KAAM,mBAAmB,KAAM,8BAA8B,KAAM,yCAAyC,KAAM,8BAA8B,KAAM,yCAAyC,KAAM,yCAAyC,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,6BAA6B,KAAM,6BAA6B,KAAM,wCAAwC,KAAM,wCAAwC,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,GAAI,QAAQ,GAAI,QAAQ,GAAI,QAAQ,GAAI,QAAQ,GAAI,QAAQ,GAAI,QAAQ,GAAI,QAAQ,IAAK,QAAQ,KAAM,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,KAAM,QAAQ,KAAM,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,mBAAmB,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,mBAAmB,IAAK,QAAQ,IAAK,mBAAmB,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,IAAK,QAAQ,GAAI,QAAQ,IAAK,QAAQ,IAAK,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,KAAM,QAAQ,IAAK,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,IAAK,QAAQ,KAAM,QAAQ,IAAK,QAAQ,GAAI,QAAQ,IAAK,QAAQ,IAAK,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,KAAM,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,IAAK,QAAQ,KAAM,QAAQ,IAAK,QAAQ,IAAK,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,IAAK,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,8BAA8B,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,mBAAmB,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,kBAAkB,KAAM,kBAAkB,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,QAAQ,KAAM,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,KAAM,OAAO,KAAM,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,KAAM,OAAO,KAAM,OAAO,KAAM,OAAO,KAAM,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,KAAM,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,IAAK,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,KAAM,OAAO,KAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,KAAM,OAAO,KAAM,OAAO,KAAM,OAAO,MAAO,OAAO,KAAM,OAAO,MAAO,OAAO,KAAM,OAAO,KAAM,OAAO,KAAM,OAAO,MAAO,iBAAiB,KAAM,iBAAiB,KAAM,OAAO,KAAM,OAAO,KAAM,OAAO,KAAM,OAAO,KAAM,OAAO,KAAM,OAAO,KAAM,OAAO,KAAM,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,kBAAkB,KAAM,kBAAkB,KAAM,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,KAAM,OAAO,MAAO,OAAO,MAAO,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,oDAAoD,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,yCAAyC,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,0CAA0C,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,yBAAyB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,cAAc,EAAG,wBAAwB,EAAG,wBAAwB,EAAG,w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","sources":["webpack://tweb/./src/components/animationIntersector.ts","webpack://tweb/./src/components/appMediaPlaybackController.ts","webpack://tweb/./src/components/appMediaViewer.ts","webpack://tweb/./src/lib/mediaPlayer.ts","webpack://tweb/./src/helpers/number/isBetween.ts","webpack://tweb/./src/components/appMediaViewerBase.ts","webpack://tweb/./src/helpers/fillPropertyValue.ts","webpack://tweb/./src/components/appNavigationController.ts","webpack://tweb/./src/components/appSearch.ts","webpack://tweb/./src/components/appSearchSuper..ts","webpack://tweb/./src/helpers/dom/lockTouchScroll.ts","webpack://tweb/./src/components/appSelectPeers.ts","webpack://tweb/./src/components/audio.ts","webpack://tweb/./src/helpers/avatarListLoader.ts","webpack://tweb/./src/components/appMediaViewerAvatar.ts","webpack://tweb/./src/components/avatar.ts","webpack://tweb/./src/components/avatarEdit.ts","webpack://tweb/./src/components/button.ts","webpack://tweb/./src/components/buttonCorner.ts","webpack://tweb/./src/components/buttonIcon.ts","webpack://tweb/./src/components/buttonMenu.ts","webpack://tweb/./src/components/buttonMenuToggle.ts","webpack://tweb/./src/components/chat/bubbleGroups.ts","webpack://tweb/./src/components/chat/replies.ts","webpack://tweb/./src/components/chat/messageRender.ts","webpack://tweb/./src/helpers/dom/superIntersectionObserver.ts","webpack://tweb/./src/lib/appManagers/utils/messages/isMentionUnread.ts","webpack://tweb/./src/components/wrappers/album.ts","webpack://tweb/./src/lib/appManagers/utils/messages/getMediaDurationFromMessage.ts","webpack://tweb/./src/components/sidebarRight/tabs/pollResults.ts","webpack://tweb/./src/components/poll.ts","webpack://tweb/./src/helpers/string/isRTL.ts","webpack://tweb/./src/components/chat/bubbles.ts","webpack://tweb/./src/helpers/dom/copyFromElement.ts","webpack://tweb/./src/components/wrappers/localSticker.ts","webpack://tweb/./src/components/wrappers/groupedDocuments.ts","webpack://tweb/./src/components/wrappers/poll.ts","webpack://tweb/./src/components/popups/reportMessagesConfirm.ts","webpack://tweb/./src/components/popups/reportMessages.ts","webpack://tweb/./src/components/popups/sponsored.ts","webpack://tweb/./src/components/popups/reactedList.ts","webpack://tweb/./src/components/chat/reactionsMenu.ts","webpack://tweb/./src/components/chat/contextMenu.ts","webpack://tweb/./src/components/chat/gradientRenderer.ts","webpack://tweb/./src/helpers/easing/easeOutQuad.ts","webpack://tweb/./src/components/popups/createPoll.ts","webpack://tweb/./src/helpers/dom/attachListNavigation.ts","webpack://tweb/./src/components/chat/autocompleteHelper.ts","webpack://tweb/./src/components/chat/stickersHelper.ts","webpack://tweb/./src/components/popups/schedule.ts","webpack://tweb/./src/components/chat/emojiHelper.ts","webpack://tweb/./src/components/chat/autocompletePeerHelper.ts","webpack://tweb/./src/components/chat/commandsHelper.ts","webpack://tweb/./src/components/chat/autocompleteHelperController.ts","webpack://tweb/./src/components/chat/mentionsHelper.ts","webpack://tweb/./src/components/chat/replyKeyboard.ts","webpack://tweb/./src/components/chat/inlineHelper.ts","webpack://tweb/./src/components/chat/botCommands.ts","webpack://tweb/./src/helpers/modifyAckedResult.ts","webpack://tweb/./src/components/chat/sendAs.ts","webpack://tweb/./src/components/chat/input.ts","webpack://tweb/./src/components/wrappers/draft.ts","webpack://tweb/./src/components/chat/reaction.ts","webpack://tweb/./src/components/chat/reactions.ts","webpack://tweb/./src/components/chat/replyContainer.ts","webpack://tweb/./src/components/chat/selection.ts","webpack://tweb/./src/helpers/dom/getSelectedText.ts","webpack://tweb/./src/components/chat/sendContextMenu.ts","webpack://tweb/./src/components/checkboxField.ts","webpack://tweb/./src/components/checkboxFields.ts","webpack://tweb/./src/components/codeInputField.ts","webpack://tweb/./src/components/confirmationPopup.ts","webpack://tweb/./src/components/countryInputField.ts","webpack://tweb/./src/components/divAndCaption.ts","webpack://tweb/./src/components/dotRenderer.ts","webpack://tweb/./src/components/editPeer.ts","webpack://tweb/./src/components/emoticonsDropdown/tabs/gifs.ts","webpack://tweb/./src/components/sidebarRight/tabs/gifs.ts","webpack://tweb/./src/components/sidebarRight/tabs/stickers.ts","webpack://tweb/./src/components/emoticonsDropdown/index.ts","webpack://tweb/./src/components/emoticonsDropdown/tabs/emoji.ts","webpack://tweb/./src/lib/richTextProcessor/wrapSingleEmoji.ts","webpack://tweb/./src/components/lazyLoadQueueRepeat.ts","webpack://tweb/./src/components/emoticonsDropdown/tabs/stickers.ts","webpack://tweb/./src/components/generateDelimiter.ts","webpack://tweb/./src/components/generateFakeIcon.ts","webpack://tweb/./src/components/lazyLoadQueueRepeat2.ts","webpack://tweb/./src/components/gifsMasonry.ts","webpack://tweb/./src/components/horizontalMenu.ts","webpack://tweb/./src/components/inputField.ts","webpack://tweb/./src/helpers/dom/selectElementContents.ts","webpack://tweb/./src/components/inputFieldAnimated.ts","webpack://tweb/./src/components/inputSearch.ts","webpack://tweb/./src/components/lazyLoadQueue.ts","webpack://tweb/./src/components/lazyLoadQueueIntersector.ts","webpack://tweb/./src/components/mediaProgressLine.ts","webpack://tweb/./src/components/middleEllipsis.ts","webpack://tweb/./src/components/monkeys/password.ts","webpack://tweb/./src/components/monkeys/tracking.ts","webpack://tweb/./src/components/passwordInputField.ts","webpack://tweb/./src/components/peerProfileAvatars.ts","webpack://tweb/./src/components/peerProfile.ts","webpack://tweb/./src/components/generateTitleIcons.ts","webpack://tweb/./src/components/generateVerifiedIcon.ts","webpack://tweb/./src/components/generatePremiumIcon.ts","webpack://tweb/./src/components/peerTitle.ts","webpack://tweb/./src/components/popups/avatar.ts","webpack://tweb/./src/lib/cropper.ts","webpack://tweb/./src/components/popups/datePicker.ts","webpack://tweb/./src/components/popups/deleteDialog.ts","webpack://tweb/./src/components/popups/deleteMessages.ts","webpack://tweb/./src/components/popups/forward.ts","webpack://tweb/./src/components/popups/index.ts","webpack://tweb/./src/components/popups/joinChatInvite.ts","webpack://tweb/./src/components/popups/limit.ts","webpack://tweb/./src/components/popups/mute.ts","webpack://tweb/./src/helpers/createPoster.ts","webpack://tweb/./src/helpers/getGifDuration.ts","webpack://tweb/./src/environment/audioMimeTypeSupport.ts","webpack://tweb/./src/components/popups/newMedia.ts","webpack://tweb/./src/helpers/cacheCallback.ts","webpack://tweb/./src/helpers/string/replaceNonNumber.ts","webpack://tweb/./src/helpers/cards/cardBrands.ts","webpack://tweb/./src/helpers/array/createArray.ts","webpack://tweb/./src/helpers/string/buggedNumbers.ts","webpack://tweb/./src/helpers/cards/patternCharacters.ts","webpack://tweb/./src/helpers/cards/cardFormattingPatterns.ts","webpack://tweb/./src/helpers/cards/formatValueByPattern.ts","webpack://tweb/./src/helpers/cards/validateCard.ts","webpack://tweb/./src/components/popups/paymentVerification.ts","webpack://tweb/./src/components/popups/paymentCard.ts","webpack://tweb/./src/helpers/cards/formatInputValueByPattern.ts","webpack://tweb/./src/components/popups/paymentCardConfirmation.ts","webpack://tweb/./src/components/popups/paymentShipping.ts","webpack://tweb/./src/components/popups/paymentShippingMethods.ts","webpack://tweb/./src/components/popups/payment.ts","webpack://tweb/./src/components/popups/peer.ts","webpack://tweb/./src/components/popups/pickUser.ts","webpack://tweb/./src/components/popups/sendNow.ts","webpack://tweb/./src/components/popups/stickers.ts","webpack://tweb/./src/components/popups/unpinMessage.ts","webpack://tweb/./src/components/preloader.ts","webpack://tweb/./src/components/groupedLayout.ts","webpack://tweb/./src/components/prepareAlbum.ts","webpack://tweb/./src/components/putPhoto.ts","webpack://tweb/./src/components/wrappers/getPeerInitials.ts","webpack://tweb/./src/components/putPreloader.ts","webpack://tweb/./src/components/radioField.ts","webpack://tweb/./src/components/radioForm.ts","webpack://tweb/./src/components/rangeSelector.ts","webpack://tweb/./src/components/ripple.ts","webpack://tweb/./src/components/row.ts","webpack://tweb/./src/components/scrollable.ts","webpack://tweb/./src/components/settingSection.ts","webpack://tweb/./src/components/sidebarLeft/tabs/newGroup.ts","webpack://tweb/./src/lib/appManagers/utils/privacy/privacyType.ts","webpack://tweb/./src/lib/appManagers/utils/privacy/getPrivacyRulesDetails.ts","webpack://tweb/./src/components/privacySection.ts","webpack://tweb/./src/components/sidebarLeft/tabs/privacy/phoneNumber.ts","webpack://tweb/./src/components/sidebarLeft/tabs/2fa/passwordSet.ts","webpack://tweb/./src/helpers/dom/canFocus.ts","webpack://tweb/./src/components/sidebarLeft/tabs/2fa/emailConfirmation.ts","webpack://tweb/./src/components/sidebarLeft/tabs/2fa/email.ts","webpack://tweb/./src/components/sidebarLeft/tabs/2fa/hint.ts","webpack://tweb/./src/components/sidebarLeft/tabs/2fa/reEnterPassword.ts","webpack://tweb/./src/components/sidebarLeft/tabs/2fa/enterPassword.ts","webpack://tweb/./src/components/sidebarLeft/tabs/2fa/index.ts","webpack://tweb/./src/components/sidebarLeft/tabs/privacy/lastSeen.ts","webpack://tweb/./src/components/sidebarLeft/tabs/privacy/profilePhoto.ts","webpack://tweb/./src/components/sidebarLeft/tabs/privacy/forwardMessages.ts","webpack://tweb/./src/components/sidebarLeft/tabs/privacy/addToGroups.ts","webpack://tweb/./src/components/sidebarLeft/tabs/privacy/calls.ts","webpack://tweb/./src/components/sidebarLeft/tabs/activeSessions.ts","webpack://tweb/./src/components/sidebarLeft/tabs/blockedUsers.ts","webpack://tweb/./src/helpers/string/convertKeyToInputKey.ts","webpack://tweb/./src/components/sidebarLeft/tabs/privacy/voices.ts","webpack://tweb/./src/components/sidebarLeft/tabs/activeWebSessions.ts","webpack://tweb/./src/components/sidebarLeft/tabs/privacyAndSecurity.ts","webpack://tweb/./src/components/sidebarLeft/tabs/powerSaving.ts","webpack://tweb/./src/components/sidebarLeft/tabs/generalSettings.ts","webpack://tweb/./src/helpers/eachMinute.ts","webpack://tweb/./src/helpers/eachTimeout.ts","webpack://tweb/./src/components/sidebarLeft/tabs/chatFolders.ts","webpack://tweb/./src/components/sidebarLeft/tabs/notifications.ts","webpack://tweb/./src/components/sidebarLeft/tabs/language.ts","webpack://tweb/./src/components/sidebarLeft/tabs/autoDownload/photo.ts","webpack://tweb/./src/components/sidebarLeft/tabs/autoDownload/file.ts","webpack://tweb/./src/components/sidebarLeft/tabs/autoDownload/video.ts","webpack://tweb/./src/components/sidebarLeft/tabs/dataAndStorage.ts","webpack://tweb/./src/components/sidebarLeft/tabs/quickReaction.ts","webpack://tweb/./src/components/sidebarLeft/tabs/stickersAndEmoji.ts","webpack://tweb/./src/components/sidebarLeft/tabs/settings.ts","webpack://tweb/./src/components/sidebarLeft/tabs/newChannel.ts","webpack://tweb/./src/components/popups/createContact.ts","webpack://tweb/./src/components/sidebarLeft/tabs/contacts.ts","webpack://tweb/./src/components/sidebarLeft/tabs/archivedTab.ts","webpack://tweb/./src/components/sidebarLeft/tabs/peopleNearby.ts","webpack://tweb/./src/components/sidebarLeft/index.ts","webpack://tweb/./src/components/sidebarLeft/tabs/addMembers.ts","webpack://tweb/./src/helpers/averageColor.ts","webpack://tweb/./src/helpers/highlightningColor.ts","webpack://tweb/./src/components/colorPicker.ts","webpack://tweb/./src/components/sidebarLeft/tabs/backgroundColor.ts","webpack://tweb/./src/components/sidebarLeft/tabs/background.ts","webpack://tweb/./src/helpers/files/requestFile.ts","webpack://tweb/./src/components/sidebarLeft/tabs/includedChats.ts","webpack://tweb/./src/components/sidebarLeft/tabs/editFolder.ts","webpack://tweb/./src/components/sidebarLeft/tabs/editProfile.ts","webpack://tweb/./src/components/sidebarRight/index.ts","webpack://tweb/./src/components/sidebarRight/tabs/editContact.ts","webpack://tweb/./src/components/sidebarRight/tabs/editTopic.ts","webpack://tweb/./src/components/sidebarRight/tabs/chatType.ts","webpack://tweb/./src/components/sidebarRight/tabs/userPermissions.ts","webpack://tweb/./src/components/sidebarRight/tabs/groupPermissions.ts","webpack://tweb/./src/lib/appManagers/utils/chats/combineParticipantBannedRights.ts","webpack://tweb/./src/components/sidebarRight/tabs/chatReactions.ts","webpack://tweb/./src/components/sidebarRight/tabs/editChat.ts","webpack://tweb/./src/components/sidebarRight/tabs/sharedMedia.ts","webpack://tweb/./src/components/singleTransition.ts","webpack://tweb/./src/components/slider.ts","webpack://tweb/./src/components/sliderTab.ts","webpack://tweb/./src/components/sortedUserList.ts","webpack://tweb/./src/components/stackedAvatars.ts","webpack://tweb/./src/components/stickerViewer.ts","webpack://tweb/./src/components/stickyIntersector.ts","webpack://tweb/./src/components/swipeHandler.ts","webpack://tweb/./src/components/telInputField.ts","webpack://tweb/./src/components/telegramWebView.ts","webpack://tweb/./src/components/toast.ts","webpack://tweb/./src/components/transition.ts","webpack://tweb/./src/lib/richTextProcessor/isUsernameValid.ts","webpack://tweb/./src/components/usernameInputField.ts","webpack://tweb/./src/components/usernamesSection.ts","webpack://tweb/./src/components/visibilityIntersector.ts","webpack://tweb/./src/components/volumeSelector.ts","webpack://tweb/./src/components/wrappers/customEmoji.ts","webpack://tweb/./src/components/wrappers/document.ts","webpack://tweb/./src/components/wrappers/formatUserPhone.ts","webpack://tweb/./src/components/wrappers/getChatMembersString.ts","webpack://tweb/./src/components/wrappers/getPeerTitle.ts","webpack://tweb/./src/components/wrappers/getUserStatusString.ts","webpack://tweb/./src/components/wrappers/mediaSpoiler.ts","webpack://tweb/./src/components/wrappers/messageActionTextNew.ts","webpack://tweb/./src/components/topicAvatar.ts","webpack://tweb/./src/components/wrappers/joinVoiceChatAnchor.ts","webpack://tweb/./src/components/wrappers/messageActionTextNewUnsafe.ts","webpack://tweb/./src/components/wrappers/messageForReply.ts","webpack://tweb/./src/components/wrappers/participantRank.ts","webpack://tweb/./src/components/wrappers/peerTitle.ts","webpack://tweb/./src/components/wrappers/photo.ts","webpack://tweb/./src/components/wrappers/reply.ts","webpack://tweb/./src/components/wrappers/senderToPeer.ts","webpack://tweb/./src/components/wrappers/sentTime.ts","webpack://tweb/./src/components/wrappers/sticker.ts","webpack://tweb/./src/helpers/bytes/getPathFromBytes.ts","webpack://tweb/./src/helpers/computeLockColor.ts","webpack://tweb/./src/components/wrappers/stickerAnimation.ts","webpack://tweb/./src/components/wrappers/stickerEmoji.ts","webpack://tweb/./src/components/wrappers/stickerSetThumb.ts","webpack://tweb/./src/components/wrappers/stickerToRow.ts","webpack://tweb/./src/components/wrappers/topicNameButton.ts","webpack://tweb/./src/components/wrappers/video.ts","webpack://tweb/./src/components/wrappers/webPageDescription.ts","webpack://tweb/./src/components/wrappers/webPageTitle.ts","webpack://tweb/./src/config/currencies.ts","webpack://tweb/./src/config/emoji.ts","webpack://tweb/./src/config/font.ts","webpack://tweb/./src/environment/imageBitmapSupport.ts","webpack://tweb/./src/helpers/animation.ts","webpack://tweb/./src/helpers/array/accumulate.ts","webpack://tweb/./src/helpers/array/filterAsync.ts","webpack://tweb/./src/helpers/array/findAndSpliceAll.ts","webpack://tweb/./src/helpers/array/partition.ts","webpack://tweb/./src/helpers/audioAssetPlayer.ts","webpack://tweb/./src/helpers/blob/readBlobAsDataURL.ts","webpack://tweb/./src/helpers/heavyQueue.ts","webpack://tweb/./src/helpers/blur.ts","webpack://tweb/./src/helpers/bytes/getPreviewURLFromBytes.ts","webpack://tweb/./src/helpers/bytes/bytesToDataURL.ts","webpack://tweb/./src/helpers/calcImageInBox.ts","webpack://tweb/./src/helpers/canvas/drawCircle.ts","webpack://tweb/./src/helpers/canvas/getTextWidth.ts","webpack://tweb/./src/helpers/canvas/scaleMediaElement.ts","webpack://tweb/./src/helpers/cleanSearchText.ts","webpack://tweb/./src/helpers/clipboard.ts","webpack://tweb/./src/helpers/contextMenuController.ts","webpack://tweb/./src/helpers/date.ts","webpack://tweb/./src/helpers/dom/anchorCopy.ts","webpack://tweb/./src/helpers/dom/attachContextMenuListener.ts","webpack://tweb/./src/helpers/dom/attachGrabListeners.ts","webpack://tweb/./src/helpers/dom/cancelSelection.ts","webpack://tweb/./src/helpers/dom/clickEvent.ts","webpack://tweb/./src/helpers/dom/controlsHover.ts","webpack://tweb/./src/helpers/dom/createContextMenu.ts","webpack://tweb/./src/helpers/dom/createStickersContextMenu.ts","webpack://tweb/./src/helpers/dom/createVideo.ts","webpack://tweb/./src/helpers/dom/customProperties.ts","webpack://tweb/./src/helpers/dom/dispatchEvent.ts","webpack://tweb/./src/helpers/dom/documentFragmentToHTML.ts","webpack://tweb/./src/helpers/dom/findUpAsChild.ts","webpack://tweb/./src/helpers/dom/findUpAttribute.ts","webpack://tweb/./src/helpers/dom/findUpTag.ts","webpack://tweb/./src/helpers/dom/fullScreen.ts","webpack://tweb/./src/helpers/dom/getCaretPosNew.ts","webpack://tweb/./src/helpers/dom/getRichElementValue.ts","webpack://tweb/./src/helpers/dom/getRichValueWithCaret.ts","webpack://tweb/./src/helpers/dom/getViewportSlice.ts","webpack://tweb/./src/helpers/dom/getVisibleRect.ts","webpack://tweb/./src/helpers/dom/handleHorizontalSwipe.ts","webpack://tweb/./src/helpers/dom/handleTabSwipe.ts","webpack://tweb/./src/helpers/dom/hasMarkupInSelection.ts","webpack://tweb/./src/helpers/dom/htmlToDocumentFragment.ts","webpack://tweb/./src/helpers/dom/htmlToSpan.ts","webpack://tweb/./src/helpers/dom/isInDOM.ts","webpack://tweb/./src/helpers/dom/isInputEmpty.ts","webpack://tweb/./src/helpers/dom/isSelectionEmpty.ts","webpack://tweb/./src/helpers/dom/isSendShortcutPressed.ts","webpack://tweb/./src/helpers/dom/isSwipingBackSafari.ts","webpack://tweb/./src/helpers/dom/placeCaretAtEnd.ts","webpack://tweb/./src/helpers/dom/positionElementByIndex.ts","webpack://tweb/./src/helpers/dom/reflowScrollableElement.ts","webpack://tweb/./src/helpers/dom/renderImageFromUrl.ts","webpack://tweb/./src/helpers/dom/renderMediaWithFadeIn.ts","webpack://tweb/./src/helpers/dom/replaceContent.ts","webpack://tweb/./src/helpers/dom/compareNodes.ts","webpack://tweb/./src/helpers/dom/richInputHandler.ts","webpack://tweb/./src/helpers/dom/shake.ts","webpack://tweb/./src/helpers/dom/sortable.ts","webpack://tweb/./src/helpers/dom/toggleDisability.ts","webpack://tweb/./src/helpers/dom/whichChild.ts","webpack://tweb/./src/helpers/dropdownHover.ts","webpack://tweb/./src/helpers/fastSmoothScroll.ts","webpack://tweb/./src/helpers/fileName.ts","webpack://tweb/./src/helpers/filterChatPhotosMessages.ts","webpack://tweb/./src/helpers/formatBytes.ts","webpack://tweb/./src/helpers/formatCallDuration.ts","webpack://tweb/./src/helpers/formatDuration.ts","webpack://tweb/./src/helpers/formatPhoneNumber.ts","webpack://tweb/./src/helpers/framesCache.ts","webpack://tweb/./src/helpers/generatePathData.ts","webpack://tweb/./src/helpers/getImageFromStrippedThumb.ts","webpack://tweb/./src/helpers/getPreviewURLFromThumb.ts","webpack://tweb/./src/helpers/getStrippedThumbIfNeeded.ts","webpack://tweb/./src/helpers/listLoader.ts","webpack://tweb/./src/helpers/listenerSetter.ts","webpack://tweb/./src/helpers/liteMode.ts","webpack://tweb/./src/helpers/mediaSize.ts","webpack://tweb/./src/helpers/mediaSizes.ts","webpack://tweb/./src/helpers/middlewarePromise.ts","webpack://tweb/./src/helpers/number/formatNumber.ts","webpack://tweb/./src/helpers/number/numberThousandSplitter.ts","webpack://tweb/./src/helpers/onMediaLoad.ts","webpack://tweb/./src/helpers/overlayClickHandler.ts","webpack://tweb/./src/helpers/paymentsWrapCurrencyAmount.ts","webpack://tweb/./src/helpers/positionMenu.ts","webpack://tweb/./src/helpers/preloadAnimatedEmojiSticker.ts","webpack://tweb/./src/helpers/restrictions.ts","webpack://tweb/./src/helpers/saveLottiePreview.ts","webpack://tweb/./src/helpers/schedulers/throttleWithRaf.ts","webpack://tweb/./src/helpers/schedulers/throttleWith.ts","webpack://tweb/./src/helpers/scrollSaver.ts","webpack://tweb/./src/helpers/scrollableLoader.ts","webpack://tweb/./src/helpers/searchListLoader.ts","webpack://tweb/./src/lib/appManagers/utils/messageId/incrementMessageId.ts","webpack://tweb/./src/helpers/sequentialDom.ts","webpack://tweb/./src/helpers/setAttachmentSize.ts","webpack://tweb/./src/helpers/sortedList.ts","webpack://tweb/./src/helpers/string/bom.ts","webpack://tweb/./src/helpers/string/encodeEntities.ts","webpack://tweb/./src/helpers/string/escapeRegExp.ts","webpack://tweb/./src/helpers/string/limitSymbols.ts","webpack://tweb/./src/helpers/string/nbsp.ts","webpack://tweb/./src/helpers/string/toHHMMSS.ts","webpack://tweb/./src/helpers/textToSvgURL.ts","webpack://tweb/./src/helpers/windowSize.ts","webpack://tweb/./src/hooks/useHeavyAnimationCheck.ts","webpack://tweb/./src/components/dialogsContextMenu.ts","webpack://tweb/./src/components/connectionStatus.ts","webpack://tweb/./src/components/sendingStatus.ts","webpack://tweb/./src/helpers/easing/easeInOutSine.ts","webpack://tweb/./src/helpers/canvas/roundRect.ts","webpack://tweb/./src/components/groupCallActiveIcon.ts","webpack://tweb/./src/helpers/canvas/shimmer.ts","webpack://tweb/./src/helpers/dialogsPlaceholder.ts","webpack://tweb/./src/lib/appManagers/appDialogsManager.ts","webpack://tweb/./src/helpers/number/getUnsafeRandomInt.ts","webpack://tweb/./src/lib/appManagers/appDownloadManager.ts","webpack://tweb/./src/helpers/dom/createDownloadAnchor.ts","webpack://tweb/./src/components/chat/pinnedContainer.ts","webpack://tweb/./src/components/chat/audio.ts","webpack://tweb/./src/components/chat/pinnedMessageBorder.ts","webpack://tweb/./src/components/chat/pinnedMessage.ts","webpack://tweb/./src/helpers/dom/handleScrollSideEvent.ts","webpack://tweb/./src/components/chat/topbar.ts","webpack://tweb/./src/components/sidebarRight/tabs/search.ts","webpack://tweb/./src/components/chat/search.ts","webpack://tweb/./src/components/chat/patternRenderer.ts","webpack://tweb/./src/components/chat/chat.ts","webpack://tweb/./src/helpers/autoDownload.ts","webpack://tweb/./src/components/chat/markupTooltip.ts","webpack://tweb/./src/components/chat/dragAndDrop.ts","webpack://tweb/./src/helpers/dom/disableTransition.ts","webpack://tweb/./src/components/lineBlobDrawable.ts","webpack://tweb/./src/components/topbarWeave.ts","webpack://tweb/./src/lib/rlottie/rlottieIcon.ts","webpack://tweb/./src/components/superIcon.ts","webpack://tweb/./src/components/groupCall/microphoneIcon.ts","webpack://tweb/./src/components/groupCall/participantMutedIcon.ts","webpack://tweb/./src/components/groupCall/index.ts","webpack://tweb/./src/components/groupCall/participantStatus.ts","webpack://tweb/./src/components/groupCall/participantsList.ts","webpack://tweb/./src/components/call/videoCanvasBlur.ts","webpack://tweb/./src/components/groupCall/participantVideo.ts","webpack://tweb/./src/components/groupCall/participantVideos.ts","webpack://tweb/./src/components/groupCall/participants.ts","webpack://tweb/./src/components/groupCall/description.ts","webpack://tweb/./src/components/groupCall/title.ts","webpack://tweb/./src/components/call/button.ts","webpack://tweb/./src/components/movableElement.ts","webpack://tweb/./src/helpers/movablePanel.ts","webpack://tweb/./src/helpers/toggleClassName.ts","webpack://tweb/./src/components/call/description.ts","webpack://tweb/./src/components/groupCall/microphoneIconMini.ts","webpack://tweb/./src/components/call/index.ts","webpack://tweb/./src/components/topbarCall.ts","webpack://tweb/./src/lib/appManagers/uiNotificationsManager.ts","webpack://tweb/./src/config/notifications.ts","webpack://tweb/./src/helpers/files/getFilesFromEvent.ts","webpack://tweb/./src/helpers/addAnchorListener.ts","webpack://tweb/./src/components/popups/giftPremium.ts","webpack://tweb/./src/lib/appManagers/appImManager.ts","webpack://tweb/./src/lib/appManagers/internalLink.ts","webpack://tweb/./src/lib/appManagers/utils/chats/getParticipantRank.ts","webpack://tweb/./src/lib/appManagers/utils/messages/canSaveMessageMedia.ts","webpack://tweb/./src/lib/appManagers/utils/messages/getMediaFromMessage.ts","webpack://tweb/./src/lib/appManagers/utils/messages/getMessageSenderPeerIdOrName.ts","webpack://tweb/./src/lib/appManagers/utils/messages/isMessageRestricted.ts","webpack://tweb/./src/lib/appManagers/utils/peers/getPeerColorById.ts","webpack://tweb/./src/lib/appManagers/utils/peers/getPeerEditableUsername.ts","webpack://tweb/./src/lib/appManagers/utils/peers/getPeerId.ts","webpack://tweb/./src/lib/appManagers/utils/photos/choosePhotoSize.ts","webpack://tweb/./src/lib/calls/callConnectionInstanceBase.ts","webpack://tweb/./src/lib/calls/helpers/createPeerConnection.ts","webpack://tweb/./src/lib/calls/helpers/createDataChannel.ts","webpack://tweb/./src/lib/calls/helpers/parseSignalingData.ts","webpack://tweb/./src/lib/calls/callConnectionInstance.ts","webpack://tweb/./src/lib/crypto/subtle.ts","webpack://tweb/./src/lib/calls/p2P/p2PEncryptor.ts","webpack://tweb/./src/lib/crypto/utils/sha256.ts","webpack://tweb/./src/lib/calls/p2P/chromeP2PSdpBuilder.ts","webpack://tweb/./src/lib/calls/p2P/p2PSdpBuilder.js","webpack://tweb/./src/lib/calls/p2P/firefoxP2PSdpBuilder.js","webpack://tweb/./src/lib/calls/p2P/safariP2PSdpBuilder.js","webpack://tweb/./src/lib/calls/callInstance.ts","webpack://tweb/./src/lib/calls/p2P/getCallProtocol.ts","webpack://tweb/./src/lib/calls/p2P/getRtcConfiguration.ts","webpack://tweb/./src/lib/calls/helpers/getStreamCached.ts","webpack://tweb/./src/lib/calls/callInstanceBase.ts","webpack://tweb/./src/lib/calls/callState.ts","webpack://tweb/./src/components/call/getAudioAsset.ts","webpack://tweb/./src/lib/calls/callsController.ts","webpack://tweb/./src/lib/calls/constants.ts","webpack://tweb/./src/lib/calls/groupCallConnectionInstance.ts","webpack://tweb/./src/lib/calls/helpers/processMediaSection.ts","webpack://tweb/./src/lib/calls/helpers/filterServerCodecs.ts","webpack://tweb/./src/lib/calls/helpers/fixLocalOffer.ts","webpack://tweb/./src/lib/calls/groupCallInstance.ts","webpack://tweb/./src/lib/calls/groupCallState.ts","webpack://tweb/./src/components/groupCall/getAudioAsset.ts","webpack://tweb/./src/lib/calls/groupCallsController.ts","webpack://tweb/./src/lib/calls/helpers/createMainStreamManager.ts","webpack://tweb/./src/lib/calls/helpers/getAudioConstraints.ts","webpack://tweb/./src/environment/constraintSupport.ts","webpack://tweb/./src/lib/calls/helpers/getScreenConstraints.ts","webpack://tweb/./src/lib/calls/helpers/getScreenStream.ts","webpack://tweb/./src/lib/calls/helpers/getStream.ts","webpack://tweb/./src/lib/calls/helpers/getVideoConstraints.ts","webpack://tweb/./src/lib/calls/helpers/parseMediaSectionInfo.ts","webpack://tweb/./src/lib/calls/helpers/parseSourceGroups.ts","webpack://tweb/./src/lib/calls/helpers/stopTrack.ts","webpack://tweb/./src/lib/calls/localConferenceDescription.ts","webpack://tweb/./src/lib/calls/sdp/index.ts","webpack://tweb/./src/helpers/string/splitStringByLimitWithRest.ts","webpack://tweb/./src/helpers/uniqueNumberGenerator.ts","webpack://tweb/./src/lib/calls/sdp/attributeSplitted.ts","webpack://tweb/./src/lib/calls/sdp/mediaLineParts.ts","webpack://tweb/./src/lib/calls/sdp/line.ts","webpack://tweb/./src/lib/calls/sdp/attributeInner.ts","webpack://tweb/./src/lib/calls/sdp/attributes.ts","webpack://tweb/./src/lib/calls/sdp/mediaSection.ts","webpack://tweb/./src/lib/calls/sdp/sessionSection.ts","webpack://tweb/./src/lib/calls/sdp/utils.ts","webpack://tweb/./src/lib/calls/sdpBuilder.ts","webpack://tweb/./src/lib/calls/streamManager.ts","webpack://tweb/./src/lib/calls/stringFromLineBuilder.ts","webpack://tweb/./src/lib/calls/utils.ts","webpack://tweb/./src/lib/mtproto/constants.ts","webpack://tweb/./src/lib/richTextProcessor/getAbbreviation.ts","webpack://tweb/./src/lib/richTextProcessor/getEmojiEntityFromEmoji.ts","webpack://tweb/./src/lib/richTextProcessor/matchEmail.ts","webpack://tweb/./src/lib/richTextProcessor/setBlankToAnchor.ts","webpack://tweb/./src/lib/richTextProcessor/wrapAbbreviation.ts","webpack://tweb/./src/lib/richTextProcessor/wrapDraftText.ts","webpack://tweb/./src/lib/richTextProcessor/wrapEmojiText.ts","webpack://tweb/./src/environment/emojiVersionsSupport.ts","webpack://tweb/./src/lib/richTextProcessor/wrapRichText.ts","webpack://tweb/./src/helpers/buildURLHash.ts","webpack://tweb/./src/lib/richTextProcessor/wrapTelegramUrlToAnchor.ts","webpack://tweb/./src/lib/rlottie/queryableWorker.ts","webpack://tweb/./src/environment/webAssemblySupport.ts","webpack://tweb/./src/lib/rlottie/lottieLoader.ts","webpack://tweb/./src/lib/rlottie/rlottiePlayer.ts","webpack://tweb/./src/pages/pagesManager.ts","webpack://tweb/./src/pages/page.ts","webpack://tweb/./src/vendor/emoji/index.ts","webpack://tweb/./public/recorder.min.js","webpack://tweb/./src/vendor/bezier-easing/index.js"],"sourcesContent":["/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {LiteModeKey} from '../helpers/liteMode';\nimport {CustomEmojiElement, CustomEmojiRendererElement} from '../lib/richTextProcessor/wrapRichText';\nimport rootScope from '../lib/rootScope';\nimport {IS_SAFARI} from '../environment/userAgent';\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport isInDOM from '../helpers/dom/isInDOM';\nimport RLottiePlayer from '../lib/rlottie/rlottiePlayer';\nimport indexOfAndSplice from '../helpers/array/indexOfAndSplice';\nimport forEachReverse from '../helpers/array/forEachReverse';\nimport idleController from '../helpers/idleController';\nimport appMediaPlaybackController from './appMediaPlaybackController';\nimport {fastRaf} from '../helpers/schedulers';\nimport {Middleware} from '../helpers/middleware';\n\nexport type AnimationItemGroup = '' | 'none' | 'chat' | 'lock' |\n 'STICKERS-POPUP' | 'emoticons-dropdown' | 'STICKERS-SEARCH' | 'GIFS-SEARCH' |\n `CHAT-MENU-REACTIONS-${number}` | 'INLINE-HELPER' | 'GENERAL-SETTINGS' | 'STICKER-VIEWER' | 'EMOJI' |\n 'EMOJI-STATUS' | `chat-${number}`;\nexport interface AnimationItem {\n el: HTMLElement,\n group: AnimationItemGroup,\n animation: AnimationItemWrapper,\n liteModeKey?: LiteModeKey,\n controlled?: boolean | Middleware\n};\n\nexport interface AnimationItemWrapper {\n remove: () => void;\n paused: boolean;\n pause: () => any;\n play: () => any;\n autoplay: boolean;\n loop: boolean | number;\n // onVisibilityChange?: (visible: boolean) => boolean;\n};\n\nexport class AnimationIntersector {\n private observer: IntersectionObserver;\n private visible: Set<AnimationItem>;\n\n private overrideIdleGroups: Set<string>;\n private byGroups: {[group in AnimationItemGroup]?: AnimationItem[]};\n private byPlayer: Map<AnimationItem['animation'], AnimationItem>;\n private lockedGroups: {[group in AnimationItemGroup]?: true};\n private onlyOnePlayableGroup: AnimationItemGroup;\n\n private intersectionLockedGroups: {[group in AnimationItemGroup]?: true};\n private videosLocked: boolean;\n\n constructor() {\n this.observer = new IntersectionObserver((entries) => {\n // if(rootScope.idle.isIDLE) return;\n\n for(const entry of entries) {\n const target = entry.target;\n\n for(const group in this.byGroups) {\n if(this.intersectionLockedGroups[group as AnimationItemGroup]) {\n continue;\n }\n\n const animation = this.byGroups[group as AnimationItemGroup].find((p) => p.el === target);\n if(!animation) {\n continue;\n }\n\n if(entry.isIntersecting) {\n this.visible.add(animation);\n this.checkAnimation(animation, false);\n\n /* if(animation instanceof HTMLVideoElement && animation.dataset.src) {\n animation.src = animation.dataset.src;\n animation.load();\n } */\n } else {\n this.visible.delete(animation);\n this.checkAnimation(animation, true);\n\n const _animation = animation.animation;\n if(_animation instanceof RLottiePlayer/* && animation.cachingDelta === 2 */) {\n // console.warn('will clear cache', player);\n _animation.clearCache();\n }/* else if(animation instanceof HTMLVideoElement && animation.src) {\n animation.dataset.src = animation.src;\n animation.src = '';\n animation.load();\n } */\n }\n\n break;\n }\n }\n });\n\n this.visible = new Set();\n\n this.overrideIdleGroups = new Set();\n this.byGroups = {};\n this.byPlayer = new Map();\n this.lockedGroups = {};\n this.onlyOnePlayableGroup = '';\n\n this.intersectionLockedGroups = {};\n this.videosLocked = false;\n\n appMediaPlaybackController.addEventListener('play', ({doc}) => {\n if(doc.type === 'round') {\n this.videosLocked = true;\n this.checkAnimations2();\n }\n });\n\n appMediaPlaybackController.addEventListener('pause', () => {\n if(this.videosLocked) {\n this.videosLocked = false;\n this.checkAnimations2();\n }\n });\n\n idleController.addEventListener('change', (idle) => {\n this.checkAnimations2(idle);\n });\n }\n\n public setOverrideIdleGroup(group: string, override: boolean) {\n if(override) this.overrideIdleGroups.add(group);\n else this.overrideIdleGroups.delete(group);\n }\n\n public getAnimations(element: HTMLElement) {\n const found: AnimationItem[] = [];\n for(const group in this.byGroups) {\n for(const player of this.byGroups[group as AnimationItemGroup]) {\n if(player.el === element) {\n found.push(player);\n }\n }\n }\n\n return found;\n }\n\n public removeAnimation(player: AnimationItem) {\n const {el, animation} = player;\n if(!(animation instanceof HTMLVideoElement)) {\n animation.remove();\n }\n\n if(animation instanceof HTMLVideoElement && IS_SAFARI) {\n setTimeout(() => { // TODO: очистка по очереди, а не все вместе с этим таймаутом\n animation.src = '';\n animation.load();\n }, 1e3);\n }\n\n const group = this.byGroups[player.group];\n if(group) {\n indexOfAndSplice(group, player);\n if(!group.length) {\n delete this.byGroups[player.group];\n }\n }\n\n this.observer.unobserve(el);\n this.visible.delete(player);\n this.byPlayer.delete(animation);\n }\n\n public removeAnimationByPlayer(player: AnimationItemWrapper) {\n const item = this.byPlayer.get(player);\n if(item) {\n this.removeAnimation(item);\n }\n }\n\n public addAnimation(options: {\n animation: AnimationItem['animation'],\n group?: AnimationItemGroup,\n observeElement?: HTMLElement,\n controlled?: AnimationItem['controlled'],\n liteModeKey?: LiteModeKey\n }) {\n let {animation, group = '', observeElement, controlled, liteModeKey} = options;\n if(group === 'none' || this.byPlayer.has(animation)) {\n return;\n }\n\n if(!observeElement) {\n if(animation instanceof RLottiePlayer) {\n observeElement = animation.el[0];\n } else if(animation instanceof CustomEmojiRendererElement) {\n observeElement = animation.canvas;\n } else if(animation instanceof CustomEmojiElement) {\n observeElement = animation.placeholder ?? animation;\n } else if(animation instanceof HTMLElement) {\n observeElement = animation;\n }\n }\n\n const item: AnimationItem = {\n el: observeElement,\n animation: animation,\n group,\n controlled,\n liteModeKey\n };\n\n if(controlled && typeof(controlled) !== 'boolean') {\n controlled.onClean(() => {\n this.removeAnimationByPlayer(animation);\n });\n }\n\n if(animation instanceof RLottiePlayer) {\n if(!rootScope.settings.stickers.loop && animation.loop) {\n animation.loop = rootScope.settings.stickers.loop;\n }\n }\n\n (this.byGroups[group as AnimationItemGroup] ??= []).push(item);\n this.observer.observe(item.el);\n this.byPlayer.set(animation, item);\n }\n\n public checkAnimations(\n blurred?: boolean,\n group?: AnimationItemGroup,\n destroy?: boolean,\n imitateIntersection?: boolean\n ) {\n // if(rootScope.idle.isIDLE) return;\n\n if(group !== undefined && !this.byGroups[group]) {\n // console.warn('no animation group:', group);\n return;\n }\n\n const groups = group !== undefined /* && false */ ? [group] : Object.keys(this.byGroups) as AnimationItemGroup[];\n\n for(const group of groups) {\n if(imitateIntersection && this.intersectionLockedGroups[group]) {\n continue;\n }\n\n const animations = this.byGroups[group];\n\n forEachReverse(animations, (animation) => {\n this.checkAnimation(animation, blurred, destroy);\n });\n }\n }\n\n public checkAnimations2(blurred?: boolean) {\n this.checkAnimations(blurred, undefined, undefined, true);\n }\n\n public checkAnimation(player: AnimationItem, blurred?: boolean, destroy?: boolean) {\n const {el, animation, group} = player;\n // return;\n if(destroy || (!this.lockedGroups[group] && !isInDOM(el))) {\n if(!player.controlled || destroy) {\n this.removeAnimation(player);\n }\n\n return;\n }\n\n if(blurred ||\n (this.onlyOnePlayableGroup && this.onlyOnePlayableGroup !== group) ||\n (animation instanceof HTMLVideoElement && this.videosLocked)\n ) {\n if(!animation.paused) {\n // console.warn('pause animation:', animation);\n animation.pause();\n }\n } else if(animation.paused &&\n this.visible.has(player) &&\n animation.autoplay &&\n (!this.onlyOnePlayableGroup || this.onlyOnePlayableGroup === group) &&\n (!idleController.isIdle || this.overrideIdleGroups.has(player.group))\n ) {\n // console.warn('play animation:', animation);\n animation.play();\n }\n }\n\n public getOnlyOnePlayableGroup() {\n return this.onlyOnePlayableGroup;\n }\n\n public setOnlyOnePlayableGroup(group: AnimationItemGroup = '') {\n this.onlyOnePlayableGroup = group;\n }\n\n public lockGroup(group: AnimationItemGroup) {\n this.lockedGroups[group] = true;\n }\n\n public unlockGroup(group: AnimationItemGroup) {\n delete this.lockedGroups[group];\n this.checkAnimations(undefined, group);\n }\n\n public refreshGroup(group: AnimationItemGroup) {\n const animations = this.byGroups[group];\n if(!animations?.length) {\n return;\n }\n\n animations.forEach((animation) => {\n this.observer.unobserve(animation.el);\n });\n\n fastRaf(() => {\n animations.forEach((animation) => {\n this.observer.observe(animation.el);\n });\n });\n }\n\n public lockIntersectionGroup(group: AnimationItemGroup) {\n this.intersectionLockedGroups[group] = true;\n }\n\n public unlockIntersectionGroup(group: AnimationItemGroup) {\n delete this.intersectionLockedGroups[group];\n this.refreshGroup(group);\n }\n\n public toggleIntersectionGroup(group: AnimationItemGroup, lock: boolean) {\n if(lock) this.lockIntersectionGroup(group);\n else this.unlockIntersectionGroup(group);\n }\n\n public setAutoplay(play: boolean, liteModeKey: LiteModeKey) {\n let changed = false;\n this.byPlayer.forEach((animationItem, animation) => {\n if(animationItem.liteModeKey === liteModeKey) {\n changed = true;\n animation.autoplay = play ? !!+animationItem.el.dataset.stickerPlay : false;\n animation.loop = play ? !!+animationItem.el.dataset.stickerLoop && rootScope.settings.stickers.loop : false;\n }\n });\n\n return changed;\n }\n\n public setLoop(loop: boolean) {\n let changed = false;\n this.byPlayer.forEach((animationItem, animation) => {\n if(!!+animationItem.el.dataset.stickerLoop &&\n animation.loop !== loop &&\n (animation instanceof RLottiePlayer || animation instanceof HTMLVideoElement)) {\n changed = true;\n animation.loop = loop;\n\n // if(animation._autoplay && animation.autoplay !== animation._autoplay) {\n animation.autoplay = !!+animationItem.el.dataset.stickerPlay;\n // }\n }\n });\n\n return changed;\n }\n}\n\nconst animationIntersector = new AnimationIntersector();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.animationIntersector = animationIntersector);\nexport default animationIntersector;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport rootScope from '../lib/rootScope';\nimport {MyDocument} from '../lib/appManagers/appDocsManager';\nimport deferredPromise, {CancellablePromise} from '../helpers/cancellablePromise';\nimport {IS_APPLE, IS_SAFARI} from '../environment/userAgent';\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport simulateEvent from '../helpers/dom/dispatchEvent';\nimport type {SearchSuperContext} from './appSearchSuper.';\nimport {Document, DocumentAttribute, Message, PhotoSize} from '../layer';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport I18n from '../lib/langPack';\nimport SearchListLoader from '../helpers/searchListLoader';\nimport copy from '../helpers/object/copy';\nimport deepEqual from '../helpers/object/deepEqual';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport getMediaFromMessage from '../lib/appManagers/utils/messages/getMediaFromMessage';\nimport getPeerTitle from './wrappers/getPeerTitle';\nimport appDownloadManager from '../lib/appManagers/appDownloadManager';\nimport onMediaLoad from '../helpers/onMediaLoad';\nimport EventListenerBase from '../helpers/eventListenerBase';\n\n// TODO: Safari: проверить стрим, включить его и сразу попробовать включить видео или другую песню\n// TODO: Safari: попробовать замаскировать подгрузку последнего чанка\n// TODO: Safari: пофиксить момент, когда заканчивается песня и пытаешься включить её заново - прогресс сразу в конце\n\nexport type MediaItem = {mid: number, peerId: PeerId};\n\ntype HTMLMediaElement = HTMLAudioElement | HTMLVideoElement;\n\nconst SHOULD_USE_SAFARI_FIX = (() => {\n try {\n return IS_SAFARI && +navigator.userAgent.match(/ Version\\/(\\d+)/)[1] < 14;\n } catch(err) {\n return false;\n }\n})();\n\nconst SEEK_OFFSET = 10;\n\nexport type MediaSearchContext = SearchSuperContext & Partial<{\n isScheduled: boolean,\n useSearch: boolean\n}>;\n\ntype MediaDetails = {\n peerId: PeerId,\n mid: number,\n docId: DocId,\n doc: MyDocument,\n message: Message.message,\n clean?: boolean,\n isScheduled?: boolean,\n isSingle?: boolean\n};\n\nexport type PlaybackMediaType = 'voice' | 'video' | 'audio';\n\nexport class AppMediaPlaybackController extends EventListenerBase<{\n play: (details: ReturnType<AppMediaPlaybackController['getPlayingDetails']>) => void,\n pause: () => void,\n playbackParams: (params: ReturnType<AppMediaPlaybackController['getPlaybackParams']>) => void,\n stop: () => void,\n}> {\n private container: HTMLElement;\n private media: Map<PeerId, Map<number, HTMLMediaElement>> = new Map();\n private scheduled: AppMediaPlaybackController['media'] = new Map();\n private mediaDetails: Map<HTMLMediaElement, MediaDetails> = new Map();\n private playingMedia: HTMLMediaElement;\n private playingMediaType: PlaybackMediaType;\n\n private waitingMediaForLoad: Map<PeerId, Map<number, CancellablePromise<void>>> = new Map();\n private waitingScheduledMediaForLoad: AppMediaPlaybackController['waitingMediaForLoad'] = new Map();\n private waitingDocumentsForLoad: {[docId: string]: Set<HTMLMediaElement>} = {};\n\n public willBePlayedMedia: HTMLMediaElement;\n private searchContext: MediaSearchContext;\n\n private listLoader: SearchListLoader<MediaItem>;\n\n public volume: number;\n public muted: boolean;\n public playbackRate: number;\n public loop: boolean;\n public round: boolean;\n private _volume: number;\n private _muted: boolean;\n private _playbackRate: number;\n private _loop: boolean;\n private _round: boolean;\n private lockedSwitchers: boolean;\n private playbackRates: Record<PlaybackMediaType, number> = {\n voice: 1,\n video: 1,\n audio: 1\n };\n\n private pip: HTMLVideoElement;\n private managers: AppManagers;\n private skipMediaPlayEvent: boolean;\n\n construct(managers: AppManagers) {\n this.managers = managers;\n this.container = document.createElement('div');\n // this.container.style.cssText = 'position: absolute; top: -10000px; left: -10000px;';\n this.container.style.cssText = 'display: none;';\n document.body.append(this.container);\n\n if(navigator.mediaSession) {\n const actions: {[action in MediaSessionAction]?: MediaSessionActionHandler} = {\n play: this.browserPlay,\n pause: this.browserPause,\n stop: this.browserStop,\n seekbackward: this.browserSeekBackward,\n seekforward: this.browserSeekForward,\n seekto: this.browserSeekTo,\n previoustrack: this.browserPrevious,\n nexttrack: this.browserNext\n };\n\n for(const action in actions) {\n try {\n navigator.mediaSession.setActionHandler(action as MediaSessionAction, actions[action as MediaSessionAction]);\n } catch(err) {\n console.warn('MediaSession action is not supported:', action);\n }\n }\n }\n\n rootScope.addEventListener('document_downloaded', (docId) => {\n const set = this.waitingDocumentsForLoad[docId];\n if(set) {\n for(const media of set) {\n this.onMediaDocumentLoad(media);\n }\n }\n });\n\n rootScope.addEventListener('media_play', () => {\n if(this.skipMediaPlayEvent) {\n this.skipMediaPlayEvent = false;\n return;\n }\n\n if(!this.pause() && this.pip) {\n this.pip.pause();\n }\n });\n\n const properties: {[key: PropertyKey]: PropertyDescriptor} = {};\n const keys = [\n 'volume' as const,\n 'muted' as const,\n 'playbackRate' as const,\n 'loop' as const,\n 'round' as const\n ];\n keys.forEach((key) => {\n const _key = ('_' + key) as `_${typeof key}`;\n properties[key] = {\n get: () => this[_key],\n set: (value: number | boolean) => {\n if(this[_key] === value) {\n return;\n }\n\n // @ts-ignore\n this[_key] = value;\n if(this.playingMedia && (key !== 'loop' || this.playingMediaType === 'audio') && key !== 'round') {\n // @ts-ignore\n this.playingMedia[key] = value;\n }\n\n if(key === 'playbackRate' && this.playingMediaType !== undefined) {\n this.playbackRates[this.playingMediaType] = value as number;\n }\n\n this.dispatchPlaybackParams();\n }\n };\n });\n Object.defineProperties(this, properties);\n }\n\n private dispatchPlaybackParams() {\n this.dispatchEvent('playbackParams', this.getPlaybackParams());\n }\n\n public getPlaybackParams() {\n const {volume, muted, playbackRate, playbackRates, loop, round} = this;\n return {\n volume,\n muted,\n playbackRate,\n playbackRates,\n loop,\n round\n };\n }\n\n public setPlaybackParams(params: ReturnType<AppMediaPlaybackController['getPlaybackParams']>) {\n this.playbackRates = params.playbackRates;\n this._volume = params.volume;\n this._muted = params.muted;\n this._playbackRate = params.playbackRate;\n this._loop = params.loop;\n this._round = params.round;\n }\n\n public seekBackward = (details: MediaSessionActionDetails, media = this.playingMedia) => {\n if(media) {\n media.currentTime = Math.max(0, media.currentTime - (details.seekOffset || SEEK_OFFSET));\n }\n };\n\n public seekForward = (details: MediaSessionActionDetails, media = this.playingMedia) => {\n if(media) {\n media.currentTime = Math.min(media.duration, media.currentTime + (details.seekOffset || SEEK_OFFSET));\n }\n };\n\n public seekTo = (details: MediaSessionActionDetails, media = this.playingMedia) => {\n if(media) {\n media.currentTime = details.seekTime;\n }\n };\n\n public addMedia(message: Message.message, autoload: boolean, clean?: boolean): HTMLMediaElement {\n const {peerId, mid} = message;\n\n const isScheduled = !!message.pFlags.is_scheduled;\n const s = isScheduled ? this.scheduled : this.media;\n let storage = s.get(message.peerId);\n if(!storage) {\n s.set(message.peerId, storage = new Map());\n }\n\n let media = storage.get(mid);\n if(media) {\n return media;\n }\n\n const doc = getMediaFromMessage(message, true) as Document.document;\n storage.set(mid, media = document.createElement(doc.type === 'round' || doc.type === 'video' ? 'video' : 'audio'));\n // const source = document.createElement('source');\n // source.type = doc.type === 'voice' && !opusDecodeController.isPlaySupported() ? 'audio/wav' : doc.mime_type;\n\n if(doc.type === 'round') {\n media.setAttribute('playsinline', 'true');\n // media.muted = true;\n }\n\n const details: MediaDetails = {\n peerId,\n mid,\n docId: doc.id,\n doc,\n message,\n clean,\n isScheduled: message.pFlags.is_scheduled\n };\n\n this.mediaDetails.set(media, details);\n\n // media.autoplay = true;\n media.volume = 1;\n // media.append(source);\n\n this.container.append(media);\n\n media.addEventListener('play', this.onPlay);\n media.addEventListener('pause', this.onPause);\n media.addEventListener('ended', this.onEnded);\n\n if(doc.type !== 'audio' && message?.pFlags.media_unread && message.fromId !== rootScope.myId) {\n media.addEventListener('timeupdate', () => {\n this.managers.appMessagesManager.readMessages(peerId, [mid]);\n }, {once: true});\n }\n\n /* const onError = (e: Event) => {\n //console.log('appMediaPlaybackController: video onError', e);\n\n if(this.nextMid === mid) {\n this.loadSiblingsMedia(peerId, doc.type as MediaType, mid).then(() => {\n if(this.nextMid && storage[this.nextMid]) {\n storage[this.nextMid].play();\n }\n });\n }\n };\n\n media.addEventListener('error', onError); */\n\n const deferred = deferredPromise<void>();\n if(autoload) {\n deferred.resolve();\n } else {\n const w = message.pFlags.is_scheduled ? this.waitingScheduledMediaForLoad : this.waitingMediaForLoad;\n let waitingStorage = w.get(peerId);\n if(!waitingStorage) {\n w.set(peerId, waitingStorage = new Map());\n }\n\n waitingStorage.set(mid, deferred);\n }\n\n deferred.then(async() => {\n // media.autoplay = true;\n // console.log('will set media url:', media, doc, doc.type, doc.url);\n\n if(doc.supportsStreaming || (await this.managers.thumbsStorage.getCacheContext(doc)).url) {\n this.onMediaDocumentLoad(media);\n } else {\n let set = this.waitingDocumentsForLoad[doc.id];\n if(!set) {\n set = this.waitingDocumentsForLoad[doc.id] = new Set();\n }\n\n set.add(media);\n appDownloadManager.downloadMediaURL({media: doc});\n }\n }/* , onError */);\n\n return media;\n }\n\n public getMedia(peerId: PeerId, mid: number, isScheduled?: boolean) {\n const s = (isScheduled ? this.scheduled : this.media).get(peerId);\n return s?.get(mid);\n }\n\n private onMediaDocumentLoad = async(media: HTMLMediaElement) => {\n const details = this.mediaDetails.get(media);\n const doc = await this.managers.appDocsManager.getDoc(details.docId);\n if(doc.type === 'audio' && doc.supportsStreaming && SHOULD_USE_SAFARI_FIX) {\n this.handleSafariStreamable(media);\n }\n\n // setTimeout(() => {\n const cacheContext = await this.managers.thumbsStorage.getCacheContext(doc);\n media.src = cacheContext.url;\n\n if(this.playingMedia === media) {\n media.playbackRate = this.playbackRate;\n\n if(doc.type === 'audio') {\n media.loop = this.loop;\n }\n }\n // }, doc.supportsStreaming ? 500e3 : 0);\n\n const set = this.waitingDocumentsForLoad[doc.id];\n if(set) {\n set.delete(media);\n\n if(!set.size) {\n delete this.waitingDocumentsForLoad[doc.id];\n }\n }\n };\n\n // safari подгрузит последний чанк и песня включится,\n // при этом этот чанк нельзя руками отдать из SW, потому что браузер тогда теряется\n private handleSafariStreamable(media: HTMLMediaElement) {\n media.addEventListener('play', () => {\n /* if(media.readyState === 4) { // https://developer.mozilla.org/ru/docs/Web/API/XMLHttpRequest/readyState\n return;\n } */\n\n // media.volume = 0;\n const currentTime = media.currentTime;\n // this.setSafariBuffering(media, true);\n\n media.addEventListener('progress', () => {\n media.currentTime = media.duration - 1;\n\n media.addEventListener('progress', () => {\n media.currentTime = currentTime;\n // media.volume = 1;\n // this.setSafariBuffering(media, false);\n\n if(!media.paused) {\n media.play()/* .catch(() => {}) */;\n }\n }, {once: true});\n }, {once: true});\n }/* , {once: true} */);\n }\n\n public resolveWaitingForLoadMedia(peerId: PeerId, mid: number, isScheduled?: boolean) {\n const w = isScheduled ? this.waitingScheduledMediaForLoad : this.waitingMediaForLoad;\n const storage = w.get(peerId);\n if(!storage) {\n return;\n }\n\n const promise = storage.get(mid);\n if(promise) {\n promise.resolve();\n storage.delete(mid);\n\n if(!storage.size) {\n w.delete(peerId);\n }\n }\n }\n\n /**\n * Only for audio\n */\n public isSafariBuffering(media: HTMLMediaElement) {\n // @ts-ignore\n return !!media.safariBuffering;\n }\n\n private setSafariBuffering(media: HTMLMediaElement, value: boolean) {\n // @ts-ignore\n media.safariBuffering = value;\n }\n\n private async setNewMediadata(message: Message.message, playingMedia = this.playingMedia) {\n if(document.pictureInPictureElement) {\n return;\n }\n\n await onMediaLoad(playingMedia, undefined, false); // have to wait for load, otherwise on macOS won't set\n\n const doc = getMediaFromMessage(message, true) as MyDocument;\n\n const artwork: MediaImage[] = [];\n\n const isVoice = doc.type === 'voice' || doc.type === 'round';\n let title = '', artist = '';\n\n if(doc.thumbs?.length) {\n const size = doc.thumbs[doc.thumbs.length - 1];\n if(!(size as PhotoSize.photoStrippedSize).bytes) {\n const cacheContext = await this.managers.thumbsStorage.getCacheContext(doc, size.type);\n\n if(cacheContext.url) {\n artwork.push({\n src: cacheContext.url,\n sizes: `${(size as PhotoSize.photoSize).w}x${(size as PhotoSize.photoSize).h}`,\n type: 'image/jpeg'\n });\n } else {\n const download = appDownloadManager.downloadMediaURL({media: doc, thumb: size});\n download.then(() => {\n if(this.playingMedia !== playingMedia || !cacheContext.url) {\n return;\n }\n\n this.setNewMediadata(message);\n });\n }\n }\n } else if(isVoice) {\n const peerId = message.fromId || message.peerId;\n const peerPhoto = await this.managers.appPeersManager.getPeerPhoto(peerId);\n if(peerPhoto) {\n // const result = this.managers.appAvatarsManager.loadAvatar(peerId, peerPhoto, 'photo_small');\n // if(result.cached) {\n // const url = await result.loadPromise;\n // artwork.push({\n // src: url,\n // sizes: '160x160',\n // type: 'image/jpeg'\n // });\n // } else {\n // result.loadPromise.then((url) => {\n // if(this.playingMedia !== playingMedia || !url) {\n // return;\n // }\n\n // this.setNewMediadata(message);\n // });\n // }\n }\n\n title = await getPeerTitle({peerId, plainText: true, onlyFirstName: false});\n artist = I18n.format(doc.type === 'voice' ? 'AttachAudio' : 'AttachRound', true);\n }\n\n if(!isVoice) {\n const attribute = doc.attributes.find((attribute) => attribute._ === 'documentAttributeAudio') as DocumentAttribute.documentAttributeAudio;\n title = attribute?.title ?? doc.file_name;\n artist = attribute?.performer;\n }\n\n if(!artwork.length) {\n if(IS_APPLE) {\n if(IS_TOUCH_SUPPORTED) {\n artwork.push({\n src: `assets/img/apple-touch-icon-precomposed.png`,\n sizes: '180x180',\n type: 'image/png'\n });\n } else {\n artwork.push({\n src: `assets/img/apple-touch-icon.png`,\n sizes: '180x180',\n type: 'image/png'\n });\n }\n } else {\n [72, 96, 144, 192, 256, 384, 512].forEach((size) => {\n const sizes = `${size}x${size}`;\n artwork.push({\n src: `assets/img/android-chrome-${sizes}.png`,\n sizes,\n type: 'image/png'\n });\n });\n }\n }\n\n const metadata = new MediaMetadata({\n title,\n artist,\n artwork\n });\n\n navigator.mediaSession.metadata = metadata;\n }\n\n public setCurrentMediadata() {\n const {playingMedia} = this;\n if(!playingMedia) return;\n const message = this.getMessageByMedia(playingMedia);\n this.setNewMediadata(message, playingMedia);\n }\n\n private getMessageByMedia(media: HTMLMediaElement): Message.message {\n const details = this.mediaDetails.get(media);\n return details.message;\n // const {peerId, mid} = details;\n // const message = details.isScheduled ?\n // this.managers.appMessagesManager.getScheduledMessageByPeer(peerId, mid) :\n // this.managers.appMessagesManager.getMessageByPeer(peerId, mid);\n // return message;\n }\n\n public getPlayingDetails() {\n const {playingMedia} = this;\n if(!playingMedia) {\n return;\n }\n\n const message = this.getMessageByMedia(playingMedia);\n return {\n doc: getMediaFromMessage(message, true) as MyDocument,\n message,\n media: playingMedia,\n playbackParams: this.getPlaybackParams()\n };\n }\n\n private onPlay = (e?: Event) => {\n const media = e.target as HTMLMediaElement;\n const details = this.mediaDetails.get(media);\n const {peerId, mid} = details;\n\n // console.log('appMediaPlaybackController: video playing', this.currentPeerId, this.playingMedia, media);\n\n const pip = this.pip;\n if(pip) {\n pip.pause();\n }\n\n const message = this.getMessageByMedia(media);\n\n const previousMedia = this.playingMedia;\n if(previousMedia !== media) {\n this.stop();\n this.setMedia(media, message);\n\n const verify = (element: MediaItem) => element.mid === mid && element.peerId === peerId;\n const listLoader = this.listLoader;\n const current = listLoader.getCurrent();\n if(!current || !verify(current)) {\n let jumpLength: number;\n\n for(const withOtherSide of [false, true]) {\n const previous = listLoader.getPrevious(withOtherSide);\n\n let idx = previous.findIndex(verify);\n if(idx !== -1) {\n jumpLength = -(previous.length - idx);\n } else {\n const next = listLoader.getNext(withOtherSide);\n idx = next.findIndex(verify);\n if(idx !== -1) {\n jumpLength = idx + 1;\n }\n }\n\n if(jumpLength !== undefined) {\n break;\n }\n }\n\n if(jumpLength) {\n this.go(jumpLength, false);\n } else {\n this.setTargets({peerId, mid});\n }\n }\n }\n\n // audio_pause не успеет сработать без таймаута\n setTimeout(() => {\n if(this.playingMedia !== media) {\n return;\n }\n\n this.dispatchEvent('play', this.getPlayingDetails());\n this.pauseMediaInOtherTabs();\n }, 0);\n };\n\n private onPause = (e?: Event) => {\n /* const target = e.target as HTMLMediaElement;\n if(!isInDOM(target)) {\n this.container.append(target);\n target.play();\n return;\n } */\n\n // if(this.pip) {\n // this.pip.play();\n // }\n\n this.dispatchEvent('pause');\n };\n\n private onEnded = (e?: Event) => {\n if(e && !e.isTrusted) {\n return;\n }\n\n this.onPause(e);\n\n // console.log('on media end');\n\n const listLoader = this.listLoader;\n if(this.lockedSwitchers ||\n (!this.round && listLoader.current && !listLoader.next.length) ||\n !listLoader.getNext(true).length ||\n !this.next()) {\n this.stop();\n this.dispatchEvent('stop');\n }\n };\n\n public pauseMediaInOtherTabs() {\n this.skipMediaPlayEvent = true;\n rootScope.dispatchEvent('media_play');\n }\n\n // public get pip() {\n // return document.pictureInPictureElement as HTMLVideoElement;\n // }\n\n public toggle(play?: boolean, media = this.playingMedia) {\n if(!media) {\n return false;\n }\n\n if(play === undefined) {\n play = media.paused;\n }\n\n if(media.paused !== play) {\n return false;\n }\n\n if(play) {\n media.play();\n } else {\n media.pause();\n }\n\n return true;\n }\n\n public play = () => {\n return this.toggle(true);\n };\n\n public pause = () => {\n return this.toggle(false);\n };\n\n public stop = (media = this.playingMedia, force?: boolean) => {\n if(!media) {\n return false;\n }\n\n if(!media.paused) {\n media.pause();\n }\n\n media.currentTime = 0;\n simulateEvent(media, 'ended'); // ! important, will be used to hide controls for audio element\n\n if(media === this.playingMedia) {\n const details = this.mediaDetails.get(media);\n if(details?.clean) {\n media.src = '';\n const peerId = details.peerId;\n const s = details.isScheduled ? this.scheduled : this.media;\n const storage = s.get(peerId);\n if(storage) {\n storage.delete(details.mid);\n\n if(!storage.size) {\n s.delete(peerId);\n }\n }\n\n media.remove();\n\n this.mediaDetails.delete(media);\n }\n\n this.playingMedia = undefined;\n this.playingMediaType = undefined;\n }\n\n if(force) {\n this.dispatchEvent('stop');\n }\n\n return true;\n };\n\n public playItem = (item: MediaItem) => {\n const {peerId, mid} = item;\n const isScheduled = this.searchContext.isScheduled;\n const media = this.getMedia(peerId, mid, isScheduled);\n\n /* if(isSafari) {\n media.autoplay = true;\n } */\n\n media.play();\n\n setTimeout(() => {\n this.resolveWaitingForLoadMedia(peerId, mid, isScheduled);\n }, 0);\n };\n\n public go = (length: number, dispatchJump?: boolean) => {\n const listLoader = this.listLoader;\n if(this.lockedSwitchers || !listLoader) {\n return;\n }\n\n if(this.playingMediaType === 'audio') {\n return listLoader.goRound(length, dispatchJump);\n } else {\n return listLoader.go(length, dispatchJump);\n }\n };\n\n private bindBrowserCallback(cb: (video: HTMLVideoElement, details: MediaSessionActionDetails) => void) {\n const handler: MediaSessionActionHandler = (details) => {\n cb(this.pip, details);\n };\n\n return handler;\n }\n\n public browserPlay = this.bindBrowserCallback((video) => this.toggle(true, video));\n public browserPause = this.bindBrowserCallback((video) => this.toggle(false, video));\n public browserStop = this.bindBrowserCallback((video) => this.stop(video));\n public browserSeekBackward = this.bindBrowserCallback((video, details) => this.seekBackward(details, video));\n public browserSeekForward = this.bindBrowserCallback((video, details) => this.seekForward(details, video));\n public browserSeekTo = this.bindBrowserCallback((video, details) => this.seekTo(details, video));\n public browserNext = this.bindBrowserCallback((video) => video || this.next());\n public browserPrevious = this.bindBrowserCallback((video) => video ? this.seekToStart(video) : this.previous());\n\n public next = () => {\n return this.go(1);\n };\n\n public previous = () => {\n if(this.seekToStart(this.playingMedia)) {\n return;\n }\n\n return this.go(-1);\n };\n\n public seekToStart(media: HTMLMediaElement) {\n if(media?.currentTime > 5) {\n media.currentTime = 0;\n this.toggle(true, media);\n return true;\n }\n\n return false;\n }\n\n public willBePlayed(media: HTMLMediaElement) {\n this.willBePlayedMedia = media;\n }\n\n public setSearchContext(context: MediaSearchContext) {\n if(deepEqual(this.searchContext, context)) {\n return false;\n }\n\n this.searchContext = copy(context); // {_: type === 'audio' ? 'inputMessagesFilterMusic' : 'inputMessagesFilterRoundVoice'}\n return true;\n }\n\n public getSearchContext() {\n return this.searchContext;\n }\n\n public setTargets(current: MediaItem, prev?: MediaItem[], next?: MediaItem[]) {\n let listLoader = this.listLoader;\n if(!listLoader) {\n listLoader = this.listLoader = new SearchListLoader({\n loadCount: 10,\n loadWhenLeft: 5,\n processItem: (message: Message.message) => {\n this.addMedia(message, false);\n return {peerId: message.peerId, mid: message.mid};\n },\n onJump: (item, older) => {\n this.playItem(item);\n },\n onEmptied: () => {\n this.dispatchEvent('stop');\n this.stop();\n }\n });\n } else {\n listLoader.reset();\n }\n\n const reverse = this.searchContext.folderId !== undefined ? false : true;\n if(prev) {\n listLoader.setTargets(prev, next, reverse);\n } else {\n listLoader.reverse = reverse;\n }\n\n listLoader.setSearchContext(this.searchContext);\n listLoader.current = current;\n\n listLoader.load(true);\n listLoader.load(false);\n }\n\n private getPlaybackMediaTypeFromMessage(message: Message.message) {\n const doc = getMediaFromMessage(message, true) as MyDocument;\n let mediaType: PlaybackMediaType = 'audio';\n if(doc?.type) {\n if(doc.type === 'voice' || doc.type === 'round') {\n mediaType = 'voice';\n } else if(doc.type === 'video') {\n mediaType = 'video';\n }\n }\n\n return mediaType;\n }\n\n public setMedia(media: HTMLMediaElement, message: Message.message) {\n const mediaType = this.getPlaybackMediaTypeFromMessage(message);\n\n this._playbackRate = this.playbackRates[mediaType];\n\n this.playingMedia = media;\n this.playingMediaType = mediaType;\n this.playingMedia.volume = this.volume;\n this.playingMedia.muted = this.muted;\n this.playingMedia.playbackRate = this.playbackRate;\n\n if(mediaType === 'audio') {\n this.playingMedia.loop = this.loop;\n }\n\n if('mediaSession' in navigator) {\n this.setNewMediadata(message);\n }\n }\n\n public setSingleMedia(media?: HTMLMediaElement, message?: Message.message) {\n const playingMedia = this.playingMedia;\n\n const wasPlaying = this.pause();\n\n let onPlay: () => void;\n if(media) {\n onPlay = () => {\n const pip = this.pip;\n if(pip) {\n pip.pause();\n }\n\n this.pauseMediaInOtherTabs();\n };\n\n if(!media.paused) {\n onPlay();\n }\n\n media.addEventListener('play', onPlay);\n } else { // maybe it's voice recording\n this.pauseMediaInOtherTabs();\n }\n\n this.willBePlayed(undefined);\n if(media) this.setMedia(media, message);\n else this.playingMedia = undefined;\n this.toggleSwitchers(false);\n\n return (playPaused = wasPlaying) => {\n this.toggleSwitchers(true);\n\n if(playingMedia) {\n if(this.mediaDetails.get(playingMedia)) {\n this.setMedia(playingMedia, this.getMessageByMedia(playingMedia));\n } else {\n this.next() || this.previous();\n }\n }\n\n // If it's still not cleaned\n if(this.playingMedia === media) {\n this.playingMedia = undefined;\n this.playingMediaType = undefined;\n }\n\n if(media) {\n media.removeEventListener('play', onPlay);\n }\n\n // I don't remember what it was for\n // if(media && this.playingMedia === media) {\n // this.stop();\n // }\n\n if(playPaused) {\n this.play();\n }\n };\n }\n\n public toggleSwitchers(enabled: boolean) {\n this.lockedSwitchers = !enabled;\n }\n\n public setPictureInPicture(video: HTMLVideoElement) {\n this.pip = video;\n\n // let wasPlaying = this.pause();\n\n const listenerSetter = new ListenerSetter();\n listenerSetter.add(video)('leavepictureinpicture', () => {\n if(this.pip !== video) {\n return;\n }\n\n this.pip = undefined;\n // if(wasPlaying) {\n // this.play();\n // }\n\n listenerSetter.removeAll();\n }, {once: true});\n\n listenerSetter.add(video)('play', (e) => {\n if(this.playingMedia !== video) {\n this.pause();\n }\n\n this.pauseMediaInOtherTabs();\n // if(this.pause()) {\n // listenerSetter.add(video)('pause', () => {\n // this.play();\n // }, {once: true});\n // }\n });\n }\n}\n\nconst appMediaPlaybackController = new AppMediaPlaybackController();\nMOUNT_CLASS_TO.appMediaPlaybackController = appMediaPlaybackController;\nexport default appMediaPlaybackController;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../lib/appManagers/appDocsManager';\nimport MEDIA_MIME_TYPES_SUPPORTED from '../environment/mediaMimeTypesSupport';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport findUpTag from '../helpers/dom/findUpTag';\nimport setInnerHTML from '../helpers/dom/setInnerHTML';\nimport mediaSizes from '../helpers/mediaSizes';\nimport SearchListLoader from '../helpers/searchListLoader';\nimport {Message} from '../layer';\nimport appDownloadManager from '../lib/appManagers/appDownloadManager';\nimport appImManager from '../lib/appManagers/appImManager';\nimport {MyMessage} from '../lib/appManagers/appMessagesManager';\nimport {MyPhoto} from '../lib/appManagers/appPhotosManager';\nimport canSaveMessageMedia from '../lib/appManagers/utils/messages/canSaveMessageMedia';\nimport getMediaFromMessage from '../lib/appManagers/utils/messages/getMediaFromMessage';\nimport wrapRichText from '../lib/richTextProcessor/wrapRichText';\nimport {MediaSearchContext} from './appMediaPlaybackController';\nimport AppMediaViewerBase, {MEDIA_VIEWER_CLASSNAME} from './appMediaViewerBase';\nimport {ButtonMenuItemOptionsVerifiable} from './buttonMenu';\nimport PopupDeleteMessages from './popups/deleteMessages';\nimport PopupForward from './popups/forward';\nimport Scrollable from './scrollable';\nimport appSidebarRight from './sidebarRight';\nimport AppSharedMediaTab from './sidebarRight/tabs/sharedMedia';\nimport PopupElement from './popups';\n\ntype AppMediaViewerTargetType = {\n element: HTMLElement,\n mid: number,\n peerId: PeerId,\n message?: MyMessage\n};\nexport default class AppMediaViewer extends AppMediaViewerBase<'caption', 'delete' | 'forward', AppMediaViewerTargetType> {\n protected listLoader: SearchListLoader<AppMediaViewerTargetType>;\n protected btnMenuForward: ButtonMenuItemOptionsVerifiable;\n protected btnMenuDownload: ButtonMenuItemOptionsVerifiable;\n protected btnMenuDelete: ButtonMenuItemOptionsVerifiable;\n\n get searchContext() {\n return this.listLoader.searchContext;\n }\n\n constructor() {\n super(new SearchListLoader({\n processItem: (item) => {\n const isForDocument = this.searchContext.inputFilter._ === 'inputMessagesFilterDocument';\n const {mid, peerId} = item;\n const media = getMediaFromMessage(item, true);\n\n if(!media) return;\n\n if(isForDocument && !AppMediaViewer.isMediaCompatibleForDocumentViewer(media)) {\n return;\n }\n\n return {element: null as HTMLElement, mid, peerId};\n }\n }), ['delete', 'forward']);\n\n this.listLoader.onEmptied = () => {\n this.close();\n };\n\n /* const stub = document.createElement('div');\n stub.classList.add(MEDIA_VIEWER_CLASSNAME + '-stub');\n this.content.main.prepend(stub); */\n\n this.content.caption = document.createElement('div');\n this.content.caption.classList.add(MEDIA_VIEWER_CLASSNAME + '-caption', 'spoilers-container'/* , 'media-viewer-stub' */);\n\n let captionTimeout: number;\n const setCaptionTimeout = () => {\n if(captionTimeout) {\n clearTimeout(captionTimeout);\n }\n\n captionTimeout = window.setTimeout(() => {\n captionTimeout = undefined;\n this.content.caption.classList.remove('is-focused');\n }, 800);\n };\n this.content.caption.addEventListener('touchstart', () => {\n if(!mediaSizes.isMobile) return;\n\n this.content.caption.classList.add('is-focused');\n\n if(captionTimeout) {\n clearTimeout(captionTimeout);\n captionTimeout = undefined;\n }\n\n document.addEventListener('touchend', setCaptionTimeout, {once: true});\n });\n\n const captionScrollable = new Scrollable(this.content.caption);\n captionScrollable.onAdditionalScroll = setCaptionTimeout;\n\n // this.content.main.append(this.content.caption);\n this.wholeDiv.append(this.content.caption);\n\n attachClickEvent(this.buttons.delete, this.onDeleteClick);\n\n const buttons: ButtonMenuItemOptionsVerifiable[] = [this.btnMenuForward = {\n icon: 'forward',\n text: 'Forward',\n onClick: this.onForwardClick\n }, this.btnMenuDownload = {\n icon: 'download',\n text: 'MediaViewer.Context.Download',\n onClick: this.onDownloadClick\n }, this.btnMenuDelete = {\n icon: 'delete danger',\n text: 'Delete',\n onClick: this.onDeleteClick\n }];\n\n this.setBtnMenuToggle(buttons);\n\n // * constructing html end\n\n this.setListeners();\n }\n\n protected setListeners() {\n super.setListeners();\n attachClickEvent(this.buttons.forward, this.onForwardClick);\n attachClickEvent(this.author.container, this.onAuthorClick);\n\n const onCaptionClick = (e: MouseEvent) => {\n const a = findUpTag(e.target, 'A');\n if(a.classList.contains('timestamp')) {\n return;\n }\n\n const spoiler = findUpClassName(e.target, 'spoiler');\n if(a instanceof HTMLAnchorElement && (!spoiler || this.content.caption.classList.contains('is-spoiler-visible'))) { // close viewer if it's t.me/ redirect\n const onclick = a.getAttribute('onclick');\n if(!onclick || onclick.includes('showMaskedAlert')) {\n return;\n }\n\n cancelEvent(e);\n\n this.close().then(() => {\n this.content.caption.removeEventListener('click', onCaptionClick, {capture: true});\n a.click();\n });\n\n return false;\n }\n };\n\n this.content.caption.addEventListener('click', onCaptionClick, {capture: true});\n }\n\n /* public close(e?: MouseEvent) {\n const good = !this.setMoverAnimationPromise;\n const promise = super.close(e);\n\n if(good) { // clear\n this.currentMessageId = 0;\n this.peerId = 0;\n }\n\n return promise;\n } */\n\n protected getMessageByPeer(peerId: PeerId, mid: number) {\n return this.searchContext.isScheduled ? this.managers.appMessagesManager.getScheduledMessageByPeer(peerId, mid) : this.managers.appMessagesManager.getMessageByPeer(peerId, mid);\n }\n\n onPrevClick = async(target: AppMediaViewerTargetType) => {\n this.openMedia({\n message: await this.getMessageByPeer(target.peerId, target.mid),\n target: target.element,\n fromRight: -1\n });\n };\n\n onNextClick = async(target: AppMediaViewerTargetType) => {\n this.openMedia({\n message: await this.getMessageByPeer(target.peerId, target.mid),\n target: target.element,\n fromRight: 1\n });\n };\n\n onDeleteClick = () => {\n const target = this.target;\n PopupElement.createPopup(PopupDeleteMessages, target.peerId, [target.mid], 'chat', () => {\n this.target = {element: this.content.media} as any;\n this.close();\n });\n };\n\n onForwardClick = () => {\n const target = this.target;\n if(target.mid) {\n // appSidebarRight.forwardTab.open([target.mid]);\n PopupElement.createPopup(PopupForward, {\n [target.peerId]: [target.mid]\n }, () => {\n return this.close();\n });\n }\n };\n\n onAuthorClick = async(e: MouseEvent) => {\n const {mid, peerId} = this.target;\n if(mid && mid !== Number.MAX_SAFE_INTEGER) {\n const threadId = this.searchContext.threadId;\n const message = await this.getMessageByPeer(peerId, mid);\n this.close(e)\n // .then(() => mediaSizes.isMobile ? appSidebarRight.sharedMediaTab.closeBtn.click() : Promise.resolve())\n .then(async() => {\n if(mediaSizes.isMobile) {\n const tab = appSidebarRight.getTab(AppSharedMediaTab);\n if(tab) {\n tab.close();\n }\n }\n\n appImManager.setInnerPeer({\n peerId: message.peerId,\n lastMsgId: mid,\n type: threadId ? 'discussion' : undefined,\n threadId\n });\n });\n }\n };\n\n onDownloadClick = () => {\n const {message} = this.target;\n const media = getMediaFromMessage(message, true);\n if(!media) return;\n appDownloadManager.downloadToDisc({media, queueId: appImManager.chat.bubbles.lazyLoadQueue.queueId});\n };\n\n private setCaption(message: MyMessage) {\n const caption = (message as Message.message).message;\n let html: Parameters<typeof setInnerHTML>[1];\n if(caption) {\n const media = getMediaFromMessage(message, true);\n\n html = wrapRichText(caption, {\n entities: (message as Message.message).totalEntities,\n maxMediaTimestamp: ((media as MyDocument)?.type === 'video' && (media as MyDocument).duration) || undefined\n });\n }\n\n // html = 'Dandelion are a family of flowering plants that grow in many parts of the world.';\n setInnerHTML(this.content.caption.firstElementChild, html);\n this.content.caption.classList.toggle('hide', !caption);\n // this.content.container.classList.toggle('with-caption', !!caption);\n }\n\n public setSearchContext(context: MediaSearchContext) {\n this.listLoader.setSearchContext(context);\n\n return this;\n }\n\n public async openMedia({\n message,\n target,\n fromRight = 0,\n reverse = false,\n prevTargets = [],\n nextTargets = [],\n mediaTimestamp\n }: {\n message: MyMessage,\n target?: HTMLElement,\n fromRight?: number,\n reverse?: boolean,\n prevTargets?: AppMediaViewerTargetType[],\n nextTargets?: AppMediaViewerTargetType[],\n mediaTimestamp?: number\n /* , needLoadMore = true */\n }) {\n if(this.setMoverPromise) return this.setMoverPromise;\n\n const mid = message.mid;\n const fromId = (message as Message.message).fwd_from && !message.fromId ? (message as Message.message).fwd_from.from_name : message.fromId;\n const media = getMediaFromMessage(message, true);\n\n const noForwards = await this.managers.appPeersManager.noForwards(message.peerId);\n const isServiceMessage = message._ === 'messageService';\n const cantForwardMessage = isServiceMessage || !(await this.managers.appMessagesManager.canForward(message));\n const cantDownloadMessage = (isServiceMessage ? noForwards : cantForwardMessage) || !canSaveMessageMedia(message);\n const a: [(HTMLElement | ButtonMenuItemOptionsVerifiable)[], boolean][] = [\n [[this.buttons.forward, this.btnMenuForward], cantForwardMessage],\n [[this.buttons.download, this.btnMenuDownload], cantDownloadMessage],\n [[this.buttons.delete, this.btnMenuDelete], !(await this.managers.appMessagesManager.canDeleteMessage(message))]\n ];\n\n a.forEach(([buttons, hide]) => {\n buttons.forEach((button) => {\n if(button instanceof HTMLElement) {\n button.classList.toggle('hide', hide);\n } else {\n button.verify = () => !hide;\n }\n });\n });\n\n this.wholeDiv.classList.toggle('no-forwards', cantDownloadMessage);\n\n this.setCaption(message);\n const promise = super._openMedia({\n media: media as MyPhoto | MyDocument,\n timestamp: message.date,\n fromId,\n fromRight,\n target,\n reverse,\n prevTargets,\n nextTargets,\n message,\n mediaTimestamp\n /* , needLoadMore */\n });\n this.target.mid = mid;\n this.target.peerId = message.peerId;\n this.target.message = message;\n\n return promise;\n }\n\n public static isMediaCompatibleForDocumentViewer(media: MyPhoto | MyDocument) {\n return media._ === 'photo' || MEDIA_MIME_TYPES_SUPPORTED.has(media.mime_type);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport appMediaPlaybackController from '../components/appMediaPlaybackController';\nimport {IS_APPLE_MOBILE, IS_MOBILE} from '../environment/userAgent';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport ListenerSetter, {Listener} from '../helpers/listenerSetter';\nimport {ButtonMenuSync} from '../components/buttonMenu';\nimport {ButtonMenuToggleHandler} from '../components/buttonMenuToggle';\nimport ControlsHover from '../helpers/dom/controlsHover';\nimport {addFullScreenListener, cancelFullScreen, isFullScreen, requestFullScreen} from '../helpers/dom/fullScreen';\nimport toHHMMSS from '../helpers/string/toHHMMSS';\nimport MediaProgressLine from '../components/mediaProgressLine';\nimport VolumeSelector from '../components/volumeSelector';\nimport debounce from '../helpers/schedulers/debounce';\nimport overlayCounter from '../helpers/overlayCounter';\nimport onMediaLoad from '../helpers/onMediaLoad';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\n\nexport default class VideoPlayer extends ControlsHover {\n private static PLAYBACK_RATES = [0.5, 1, 1.5, 2];\n private static PLAYBACK_RATES_ICONS = ['playback_05', 'playback_1x', 'playback_15', 'playback_2x'];\n\n protected video: HTMLVideoElement;\n protected wrapper: HTMLDivElement;\n protected progress: MediaProgressLine;\n protected skin: 'default';\n\n protected listenerSetter: ListenerSetter;\n protected playbackRateButton: HTMLElement;\n protected pipButton: HTMLElement;\n\n /* protected videoParent: HTMLElement;\n protected videoWhichChild: number; */\n\n protected onPlaybackRackMenuToggle?: (open: boolean) => void;\n protected onPip?: (pip: boolean) => void;\n protected onPipClose?: () => void;\n\n constructor({\n video,\n play = false,\n streamable = false,\n duration,\n onPlaybackRackMenuToggle,\n onPip,\n onPipClose\n }: {\n video: HTMLVideoElement,\n play?: boolean,\n streamable?: boolean,\n duration?: number,\n onPlaybackRackMenuToggle?: VideoPlayer['onPlaybackRackMenuToggle'],\n onPip?: VideoPlayer['onPip'],\n onPipClose?: VideoPlayer['onPipClose']\n }) {\n super();\n\n this.video = video;\n this.wrapper = document.createElement('div');\n this.wrapper.classList.add('ckin__player');\n\n this.onPlaybackRackMenuToggle = onPlaybackRackMenuToggle;\n this.onPip = onPip;\n this.onPipClose = onPipClose;\n\n this.listenerSetter = new ListenerSetter();\n\n this.setup({\n element: this.wrapper,\n listenerSetter: this.listenerSetter,\n canHideControls: () => {\n return !this.video.paused && (!this.playbackRateButton || !this.playbackRateButton.classList.contains('menu-open'));\n },\n showOnLeaveToClassName: 'media-viewer-caption',\n ignoreClickClassName: 'ckin__controls'\n });\n\n video.parentNode.insertBefore(this.wrapper, video);\n this.wrapper.appendChild(video);\n\n this.skin = 'default';\n\n this.stylePlayer(duration);\n this.setBtnMenuToggle();\n\n if(this.skin === 'default') {\n const controls = this.wrapper.querySelector('.default__controls.ckin__controls') as HTMLDivElement;\n this.progress = new MediaProgressLine({\n onSeekStart: () => {\n this.wrapper.classList.add('is-seeking');\n },\n onSeekEnd: () => {\n this.wrapper.classList.remove('is-seeking');\n }\n });\n this.progress.setMedia({\n media: video,\n streamable,\n duration\n });\n controls.prepend(this.progress.container);\n }\n\n if(play/* && video.paused */) {\n const promise = video.play();\n promise.catch((err: Error) => {\n if(err.name === 'NotAllowedError') {\n video.muted = true;\n video.autoplay = true;\n video.play();\n }\n }).finally(() => { // due to autoplay, play will not call\n this.wrapper.classList.toggle('is-playing', !this.video.paused);\n });\n }\n }\n\n private stylePlayer(initDuration: number) {\n const {wrapper, video, skin, listenerSetter} = this;\n\n wrapper.classList.add(skin);\n\n const html = this.buildControls();\n wrapper.insertAdjacentHTML('beforeend', html);\n let timeDuration: HTMLElement;\n\n if(skin === 'default') {\n this.playbackRateButton = this.wrapper.querySelector('.playback-rate') as HTMLElement;\n this.pipButton = this.wrapper.querySelector('.pip') as HTMLElement;\n\n const toggle = wrapper.querySelectorAll('.toggle') as NodeListOf<HTMLElement>;\n const fullScreenButton = wrapper.querySelector('.fullscreen') as HTMLElement;\n const timeElapsed = wrapper.querySelector('#time-elapsed');\n timeDuration = wrapper.querySelector('#time-duration') as HTMLElement;\n timeDuration.textContent = toHHMMSS(video.duration | 0);\n\n const volumeSelector = new VolumeSelector(listenerSetter);\n\n const leftControls = wrapper.querySelector('.left-controls');\n volumeSelector.btn.classList.remove('btn-icon');\n leftControls.insertBefore(volumeSelector.btn, timeElapsed.parentElement);\n\n Array.from(toggle).forEach((button) => {\n attachClickEvent(button, () => {\n this.togglePlay();\n }, {listenerSetter: this.listenerSetter});\n });\n\n if(this.pipButton) {\n attachClickEvent(this.pipButton, () => {\n this.video.requestPictureInPicture();\n }, {listenerSetter: this.listenerSetter});\n\n const onPip = (pip: boolean) => {\n this.wrapper.style.visibility = pip ? 'hidden': '';\n if(this.onPip) {\n this.onPip(pip);\n }\n };\n\n const debounceTime = 20;\n const debouncedPip = debounce(onPip, debounceTime, false, true);\n\n listenerSetter.add(video)('enterpictureinpicture', () => {\n debouncedPip(true);\n\n listenerSetter.add(video)('leavepictureinpicture', () => {\n const onPause = () => {\n clearTimeout(timeout);\n if(this.onPipClose) {\n this.onPipClose();\n }\n };\n const listener = listenerSetter.add(video)('pause', onPause, {once: true}) as any as Listener;\n const timeout = setTimeout(() => {\n listenerSetter.remove(listener);\n }, debounceTime);\n }, {once: true});\n });\n\n listenerSetter.add(video)('leavepictureinpicture', () => {\n debouncedPip(false);\n });\n }\n\n if(!IS_TOUCH_SUPPORTED) {\n attachClickEvent(video, () => {\n this.togglePlay();\n }, {listenerSetter: this.listenerSetter});\n\n listenerSetter.add(document)('keydown', (e: KeyboardEvent) => {\n if(overlayCounter.overlaysActive > 1 || document.pictureInPictureElement === video) { // forward popup is active, etc\n return;\n }\n\n const {key, code} = e;\n\n let good = true;\n if(code === 'KeyF') {\n this.toggleFullScreen();\n } else if(code === 'KeyM') {\n appMediaPlaybackController.muted = !appMediaPlaybackController.muted;\n } else if(code === 'Space') {\n this.togglePlay();\n } else if(e.altKey && (code === 'Equal' || code === 'Minus')) {\n const add = code === 'Equal' ? 1 : -1;\n const playbackRate = appMediaPlaybackController.playbackRate;\n const idx = VideoPlayer.PLAYBACK_RATES.indexOf(playbackRate);\n const nextIdx = idx + add;\n if(nextIdx >= 0 && nextIdx < VideoPlayer.PLAYBACK_RATES.length) {\n appMediaPlaybackController.playbackRate = VideoPlayer.PLAYBACK_RATES[nextIdx];\n }\n } else if(wrapper.classList.contains('ckin__fullscreen') && (key === 'ArrowLeft' || key === 'ArrowRight')) {\n if(key === 'ArrowLeft') appMediaPlaybackController.seekBackward({action: 'seekbackward'});\n else appMediaPlaybackController.seekForward({action: 'seekforward'});\n } else {\n good = false;\n }\n\n if(good) {\n cancelEvent(e);\n return false;\n }\n });\n }\n\n listenerSetter.add(video)('dblclick', () => {\n if(!IS_TOUCH_SUPPORTED) {\n this.toggleFullScreen();\n }\n });\n\n attachClickEvent(fullScreenButton, () => {\n this.toggleFullScreen();\n }, {listenerSetter: this.listenerSetter});\n\n addFullScreenListener(wrapper, this.onFullScreen.bind(this, fullScreenButton), listenerSetter);\n\n listenerSetter.add(video)('timeupdate', () => {\n timeElapsed.textContent = toHHMMSS(video.currentTime | 0);\n });\n\n listenerSetter.add(video)('play', () => {\n wrapper.classList.add('played');\n\n if(!IS_TOUCH_SUPPORTED) {\n listenerSetter.add(video)('play', () => {\n this.hideControls(true);\n });\n }\n }, {once: true});\n\n listenerSetter.add(video)('pause', () => {\n this.showControls(false);\n });\n\n listenerSetter.add(appMediaPlaybackController)('playbackParams', () => {\n this.setPlaybackRateIcon();\n });\n }\n\n listenerSetter.add(video)('play', () => {\n wrapper.classList.add('is-playing');\n });\n\n listenerSetter.add(video)('pause', () => {\n wrapper.classList.remove('is-playing');\n });\n\n if(video.duration || initDuration) {\n timeDuration.textContent = toHHMMSS(Math.round(video.duration || initDuration));\n } else {\n onMediaLoad(video).then(() => {\n timeDuration.textContent = toHHMMSS(Math.round(video.duration));\n });\n }\n }\n\n protected togglePlay(isPaused = this.video.paused) {\n this.video[isPaused ? 'play' : 'pause']();\n }\n\n private buildControls() {\n const skin = this.skin;\n if(skin === 'default') {\n return `\n <button class=\"${skin}__button--big toggle tgico\" title=\"Toggle Play\"></button>\n <div class=\"${skin}__gradient-bottom ckin__controls\"></div>\n <div class=\"${skin}__controls ckin__controls\">\n <div class=\"bottom-controls\">\n <div class=\"left-controls\">\n <button class=\"btn-icon ${skin}__button toggle tgico\" title=\"Toggle Video\"></button>\n <div class=\"time\">\n <time id=\"time-elapsed\">0:00</time>\n <span> / </span>\n <time id=\"time-duration\">0:00</time>\n </div>\n </div>\n <div class=\"right-controls\">\n <button class=\"btn-icon ${skin}__button btn-menu-toggle playback-rate night\" title=\"Playback Rate\"></button>\n ${!IS_MOBILE && document.pictureInPictureEnabled ? `<button class=\"btn-icon ${skin}__button pip tgico-pip\" title=\"Picture-in-Picture\"></button>` : ''}\n <button class=\"btn-icon ${skin}__button fullscreen tgico-fullscreen\" title=\"Full Screen\"></button>\n </div>\n </div>\n </div>`;\n }\n }\n\n protected setBtnMenuToggle() {\n const buttons = VideoPlayer.PLAYBACK_RATES.map((rate, idx) => {\n const buttonOptions: Parameters<typeof ButtonMenuSync>[0]['buttons'][0] = {\n // icon: VideoPlayer.PLAYBACK_RATES_ICONS[idx],\n regularText: rate + 'x',\n onClick: () => {\n appMediaPlaybackController.playbackRate = rate;\n }\n };\n\n return buttonOptions;\n });\n const btnMenu = ButtonMenuSync({buttons});\n btnMenu.classList.add('top-left');\n ButtonMenuToggleHandler({\n el: this.playbackRateButton,\n onOpen: this.onPlaybackRackMenuToggle ? () => {\n this.onPlaybackRackMenuToggle(true);\n } : undefined,\n onClose: this.onPlaybackRackMenuToggle ? () => {\n this.onPlaybackRackMenuToggle(false);\n } : undefined\n });\n this.playbackRateButton.append(btnMenu);\n\n this.setPlaybackRateIcon();\n }\n\n protected setPlaybackRateIcon() {\n const playbackRateButton = this.playbackRateButton;\n VideoPlayer.PLAYBACK_RATES_ICONS.forEach((className) => {\n className = 'tgico-' + className;\n playbackRateButton.classList.remove(className);\n });\n\n let idx = VideoPlayer.PLAYBACK_RATES.indexOf(appMediaPlaybackController.playbackRate);\n if(idx === -1) idx = VideoPlayer.PLAYBACK_RATES.indexOf(1);\n\n playbackRateButton.classList.add('tgico-' + VideoPlayer.PLAYBACK_RATES_ICONS[idx]);\n }\n\n protected toggleFullScreen() {\n const player = this.wrapper;\n\n // * https://caniuse.com/#feat=fullscreen\n if(IS_APPLE_MOBILE) {\n const video = this.video as any;\n video.webkitEnterFullscreen();\n video.enterFullscreen();\n return;\n }\n\n if(!isFullScreen()) {\n /* const videoParent = this.video.parentElement;\n const videoWhichChild = whichChild(this.video);\n const needVideoRemount = videoParent !== player;\n\n if(needVideoRemount) {\n this.videoParent = videoParent;\n this.videoWhichChild = videoWhichChild;\n player.prepend(this.video);\n } */\n\n requestFullScreen(player);\n } else {\n /* if(this.videoParent) {\n const {videoWhichChild, videoParent} = this;\n if(!videoWhichChild) {\n videoParent.prepend(this.video);\n } else {\n videoParent.insertBefore(this.video, videoParent.children[videoWhichChild]);\n }\n\n this.videoParent = null;\n this.videoWhichChild = -1;\n } */\n\n cancelFullScreen();\n }\n }\n\n protected onFullScreen(fullScreenButton: HTMLElement) {\n const isFull = isFullScreen();\n this.wrapper.classList.toggle('ckin__fullscreen', isFull);\n if(!isFull) {\n fullScreenButton.classList.remove('tgico-smallscreen');\n fullScreenButton.classList.add('tgico-fullscreen');\n fullScreenButton.setAttribute('title', 'Full Screen');\n } else {\n fullScreenButton.classList.remove('tgico-fullscreen');\n fullScreenButton.classList.add('tgico-smallscreen');\n fullScreenButton.setAttribute('title', 'Exit Full Screen');\n }\n }\n\n public setTimestamp(timestamp: number) {\n this.video.currentTime = timestamp;\n this.togglePlay(true);\n }\n\n public cleanup() {\n super.cleanup();\n this.listenerSetter.removeAll();\n this.progress.removeListeners();\n this.onPlaybackRackMenuToggle = this.onPip = undefined;\n }\n}\n","export default function isBetween(num: number, min: number, max: number) {\n return num >= min && num <= max;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// * zoom part from WebZ\n// * https://github.com/Ajaxy/telegram-tt/blob/069f4f5b2f2c7c22529ccced876842e7f9cb81f4/src/components/mediaViewer/MediaViewerSlides.tsx\n\nimport type {MyDocument} from '../lib/appManagers/appDocsManager';\nimport type {MyPhoto} from '../lib/appManagers/appPhotosManager';\nimport deferredPromise from '../helpers/cancellablePromise';\nimport mediaSizes from '../helpers/mediaSizes';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport {IS_MOBILE, IS_MOBILE_SAFARI, IS_SAFARI} from '../environment/userAgent';\nimport {logger} from '../lib/logger';\nimport VideoPlayer from '../lib/mediaPlayer';\nimport rootScope from '../lib/rootScope';\nimport animationIntersector from './animationIntersector';\nimport appMediaPlaybackController, {AppMediaPlaybackController} from './appMediaPlaybackController';\nimport AvatarElement from './avatar';\nimport ButtonIcon from './buttonIcon';\nimport {ButtonMenuItemOptions} from './buttonMenu';\nimport ButtonMenuToggle from './buttonMenuToggle';\nimport ProgressivePreloader from './preloader';\nimport SwipeHandler, {ZoomDetails} from './swipeHandler';\nimport {formatFullSentTime} from '../helpers/date';\nimport appNavigationController, {NavigationItem} from './appNavigationController';\nimport {Message, PhotoSize} from '../layer';\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport renderImageFromUrl, {renderImageFromUrlPromise} from '../helpers/dom/renderImageFromUrl';\nimport getVisibleRect from '../helpers/dom/getVisibleRect';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport fillPropertyValue from '../helpers/fillPropertyValue';\nimport generatePathData from '../helpers/generatePathData';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport {doubleRaf, fastRaf} from '../helpers/schedulers';\nimport RangeSelector from './rangeSelector';\nimport windowSize from '../helpers/windowSize';\nimport ListLoader from '../helpers/listLoader';\nimport EventListenerBase from '../helpers/eventListenerBase';\nimport {MyMessage} from '../lib/appManagers/appMessagesManager';\nimport {NULL_PEER_ID} from '../lib/mtproto/mtproto_config';\nimport {isFullScreen} from '../helpers/dom/fullScreen';\nimport {attachClickEvent, hasMouseMovedSinceDown} from '../helpers/dom/clickEvent';\nimport SearchListLoader from '../helpers/searchListLoader';\nimport createVideo from '../helpers/dom/createVideo';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport getStrippedThumbIfNeeded from '../helpers/getStrippedThumbIfNeeded';\nimport setAttachmentSize from '../helpers/setAttachmentSize';\nimport wrapEmojiText from '../lib/richTextProcessor/wrapEmojiText';\nimport LazyLoadQueueBase from './lazyLoadQueueBase';\nimport overlayCounter from '../helpers/overlayCounter';\nimport appDownloadManager from '../lib/appManagers/appDownloadManager';\nimport wrapPeerTitle from './wrappers/peerTitle';\nimport {toastNew} from './toast';\nimport clamp from '../helpers/number/clamp';\nimport debounce from '../helpers/schedulers/debounce';\nimport isBetween from '../helpers/number/isBetween';\nimport findUpAsChild from '../helpers/dom/findUpAsChild';\nimport liteMode from '../helpers/liteMode';\n\nconst ZOOM_STEP = 0.5;\nconst ZOOM_INITIAL_VALUE = 1;\nconst ZOOM_MIN_VALUE = 0.5;\nconst ZOOM_MAX_VALUE = 4;\n\nexport const MEDIA_VIEWER_CLASSNAME = 'media-viewer';\n\ntype Transform = {\n x: number;\n y: number;\n scale: number;\n};\n\nexport default class AppMediaViewerBase<\n ContentAdditionType extends string,\n ButtonsAdditionType extends string,\n TargetType extends {element: HTMLElement\n}> extends EventListenerBase<{\n setMoverBefore: () => void,\n setMoverAfter: () => void\n}> {\n protected wholeDiv: HTMLElement;\n protected overlaysDiv: HTMLElement;\n protected author: {[k in 'container' | 'avatarEl' | 'nameEl' | 'date']: HTMLElement} = {} as any;\n protected content: {[k in 'main' | 'container' | 'media' | 'mover' | ContentAdditionType]: HTMLElement} = {} as any;\n protected buttons: {[k in 'download' | 'close' | 'prev' | 'next' | 'mobile-close' | 'zoom' | ButtonsAdditionType]: HTMLElement} = {} as any;\n protected topbar: HTMLElement;\n protected moversContainer: HTMLElement;\n\n protected tempId = 0;\n protected preloader: ProgressivePreloader = null;\n protected preloaderStreamable: ProgressivePreloader = null;\n\n protected log: ReturnType<typeof logger>;\n\n protected isFirstOpen = true;\n\n protected pageEl = document.getElementById('page-chats') as HTMLDivElement;\n\n protected setMoverPromise: Promise<void>;\n protected setMoverAnimationPromise: Promise<void>;\n\n protected lazyLoadQueue: LazyLoadQueueBase;\n\n protected highlightSwitchersTimeout: number;\n\n protected onDownloadClick: (e: MouseEvent) => void;\n protected onPrevClick: (target: TargetType) => void;\n protected onNextClick: (target: TargetType) => void;\n\n protected videoPlayer: VideoPlayer;\n\n protected zoomElements: {\n container: HTMLElement,\n btnOut: HTMLElement,\n btnIn: HTMLElement,\n rangeSelector: RangeSelector\n } = {} as any;\n protected transform: Transform = {x: 0, y: 0, scale: ZOOM_INITIAL_VALUE};\n protected isZooming: boolean;\n protected isGesturingNow: boolean;\n protected isZoomingNow: boolean;\n protected draggingType: 'wheel' | 'touchmove' | 'mousemove';\n protected initialContentRect: DOMRect;\n\n protected ctrlKeyDown: boolean;\n protected releaseSingleMedia: ReturnType<AppMediaPlaybackController['setSingleMedia']>;\n protected navigationItem: NavigationItem;\n\n protected managers: AppManagers;\n protected swipeHandler: SwipeHandler;\n protected closing: boolean;\n\n protected lastTransform: Transform = this.transform;\n protected lastZoomCenter: {x: number, y: number} = this.transform;\n protected lastDragOffset: {x: number, y: number} = this.transform;\n protected lastDragDelta: {x: number, y: number} = this.transform;\n protected lastGestureTime: number;\n protected clampZoomDebounced: ReturnType<typeof debounce<() => void>>;\n protected ignoreNextClick: boolean;\n\n get target() {\n return this.listLoader.current;\n }\n\n set target(value) {\n this.listLoader.current = value;\n }\n\n constructor(\n protected listLoader: ListLoader<TargetType, any>,\n topButtons: Array<keyof AppMediaViewerBase<ContentAdditionType, ButtonsAdditionType, TargetType>['buttons']>\n ) {\n super(false);\n\n this.managers = rootScope.managers;\n\n this.log = logger('AMV');\n this.preloader = new ProgressivePreloader();\n this.preloaderStreamable = new ProgressivePreloader({\n cancelable: false,\n streamable: true\n });\n this.preloader.construct();\n this.preloaderStreamable.construct();\n this.lazyLoadQueue = new LazyLoadQueueBase();\n\n this.wholeDiv = document.createElement('div');\n this.wholeDiv.classList.add(MEDIA_VIEWER_CLASSNAME + '-whole');\n\n this.overlaysDiv = document.createElement('div');\n this.overlaysDiv.classList.add('overlays');\n\n const mainDiv = document.createElement('div');\n mainDiv.classList.add(MEDIA_VIEWER_CLASSNAME);\n\n const topbar = this.topbar = document.createElement('div');\n topbar.classList.add(MEDIA_VIEWER_CLASSNAME + '-topbar', MEDIA_VIEWER_CLASSNAME + '-appear');\n\n const topbarLeft = document.createElement('div');\n topbarLeft.classList.add(MEDIA_VIEWER_CLASSNAME + '-topbar-left');\n\n this.buttons['mobile-close'] = ButtonIcon('close', {onlyMobile: true});\n\n // * author\n this.author.container = document.createElement('div');\n this.author.container.classList.add(MEDIA_VIEWER_CLASSNAME + '-author', 'no-select');\n const authorRight = document.createElement('div');\n\n this.author.avatarEl = new AvatarElement();\n this.author.avatarEl.classList.add(MEDIA_VIEWER_CLASSNAME + '-userpic', 'avatar-44');\n\n this.author.nameEl = document.createElement('div');\n this.author.nameEl.classList.add(MEDIA_VIEWER_CLASSNAME + '-name');\n\n this.author.date = document.createElement('div');\n this.author.date.classList.add(MEDIA_VIEWER_CLASSNAME + '-date');\n\n authorRight.append(this.author.nameEl, this.author.date);\n\n this.author.container.append(this.author.avatarEl, authorRight);\n\n // * buttons\n const buttonsDiv = document.createElement('div');\n buttonsDiv.classList.add(MEDIA_VIEWER_CLASSNAME + '-buttons');\n\n topButtons.concat(['download', 'zoom', 'close']).forEach((name) => {\n const button = ButtonIcon(name, {noRipple: true});\n this.buttons[name] = button;\n buttonsDiv.append(button);\n });\n\n this.buttons.zoom.classList.add('zoom-in');\n\n // * zoom\n this.zoomElements.container = document.createElement('div');\n this.zoomElements.container.classList.add('zoom-container');\n\n this.zoomElements.btnOut = ButtonIcon('zoomout', {noRipple: true});\n attachClickEvent(this.zoomElements.btnOut, () => this.addZoomStep(false));\n this.zoomElements.btnIn = ButtonIcon('zoomin', {noRipple: true});\n attachClickEvent(this.zoomElements.btnIn, () => this.addZoomStep(true));\n\n this.zoomElements.rangeSelector = new RangeSelector({\n step: 0.01,\n min: ZOOM_MIN_VALUE,\n max: ZOOM_MAX_VALUE,\n withTransition: true\n }, ZOOM_INITIAL_VALUE);\n this.zoomElements.rangeSelector.setListeners();\n this.zoomElements.rangeSelector.setHandlers({\n onScrub: (value) => {\n const add = value - this.transform.scale;\n this.addZoom(add);\n this.clampZoomDebounced?.clearTimeout();\n },\n onMouseDown: () => {\n this.onSwipeFirst();\n },\n onMouseUp: () => {\n this.onSwipeReset();\n }\n });\n\n this.zoomElements.container.append(this.zoomElements.btnOut, this.zoomElements.rangeSelector.container, this.zoomElements.btnIn);\n\n if(!IS_TOUCH_SUPPORTED) {\n this.wholeDiv.append(this.zoomElements.container);\n }\n\n // * content\n this.content.main = document.createElement('div');\n this.content.main.classList.add(MEDIA_VIEWER_CLASSNAME + '-content');\n\n this.content.container = document.createElement('div');\n this.content.container.classList.add(MEDIA_VIEWER_CLASSNAME + '-container');\n\n this.content.media = document.createElement('div');\n this.content.media.classList.add(MEDIA_VIEWER_CLASSNAME + '-media');\n\n this.content.container.append(this.content.media);\n\n this.content.main.append(this.content.container);\n mainDiv.append(this.content.main);\n this.overlaysDiv.append(mainDiv);\n // * overlays end\n\n topbarLeft.append(this.buttons['mobile-close'], this.author.container);\n topbar.append(topbarLeft, buttonsDiv);\n\n this.buttons.prev = document.createElement('div');\n this.buttons.prev.className = `${MEDIA_VIEWER_CLASSNAME}-switcher ${MEDIA_VIEWER_CLASSNAME}-switcher-left`;\n this.buttons.prev.innerHTML = `<span class=\"tgico-down ${MEDIA_VIEWER_CLASSNAME}-prev-button\"></span>`;\n\n this.buttons.next = document.createElement('div');\n this.buttons.next.className = `${MEDIA_VIEWER_CLASSNAME}-switcher ${MEDIA_VIEWER_CLASSNAME}-switcher-right`;\n this.buttons.next.innerHTML = `<span class=\"tgico-down ${MEDIA_VIEWER_CLASSNAME}-next-button\"></span>`;\n\n this.moversContainer = document.createElement('div');\n this.moversContainer.classList.add(MEDIA_VIEWER_CLASSNAME + '-movers');\n\n this.moversContainer.append(this.buttons.prev, this.buttons.next);\n\n this.wholeDiv.append(this.overlaysDiv, /* this.buttons.prev, this.buttons.next, */ this.topbar, this.moversContainer);\n\n // * constructing html end\n\n this.listLoader.onLoadedMore = () => {\n this.buttons.prev.classList.toggle('hide', !this.listLoader.previous.length);\n this.buttons.next.classList.toggle('hide', !this.listLoader.next.length);\n };\n\n this.setNewMover();\n }\n\n protected setListeners() {\n attachClickEvent(this.buttons.download, this.onDownloadClick);\n [this.buttons.close, this.buttons['mobile-close'], this.preloaderStreamable.preloader].forEach((el) => {\n attachClickEvent(el, this.close.bind(this));\n });\n\n ([[-1, this.buttons.prev], [1, this.buttons.next]] as [number, HTMLElement][]).forEach(([moveLength, button]) => {\n // attachClickEvent(button, (e) => {\n button.addEventListener('click', (e) => {\n cancelEvent(e);\n if(this.setMoverPromise) return;\n\n this.listLoader.go(moveLength);\n });\n });\n\n attachClickEvent(this.buttons.zoom, () => {\n if(this.isZooming) this.resetZoom();\n else {\n this.addZoomStep(true);\n }\n });\n\n // ! cannot use the function because it'll cancel slide event on touch devices\n // attachClickEvent(this.wholeDiv, this.onClick);\n this.wholeDiv.addEventListener('click', this.onClick);\n\n this.listLoader.onJump = (item, older) => {\n if(older) this.onNextClick(item);\n else this.onPrevClick(item);\n };\n\n const adjustPosition = (xDiff: number, yDiff: number) => {\n const [x, y] = [xDiff - this.lastDragOffset.x, yDiff - this.lastDragOffset.y];\n const [transform, inBoundsX, inBoundsY] = this.calculateOffsetBoundaries({\n x: this.transform.x + x,\n y: this.transform.y + y,\n scale: this.transform.scale\n });\n\n this.lastDragDelta = {\n x,\n y\n };\n\n this.lastDragOffset = {\n x: xDiff,\n y: yDiff\n };\n\n this.setTransform(transform);\n\n return {inBoundsX, inBoundsY};\n };\n\n const setLastGestureTime = debounce(() => {\n this.lastGestureTime = Date.now();\n }, 500, false, true);\n\n this.clampZoomDebounced = debounce(() => {\n this.onSwipeReset();\n }, 300, false, true);\n\n this.swipeHandler = new SwipeHandler({\n element: this.wholeDiv,\n onReset: this.onSwipeReset,\n onFirstSwipe: this.onSwipeFirst as any,\n onSwipe: (xDiff, yDiff, e, cancelDrag) => {\n if(isFullScreen()) {\n return;\n }\n\n if(this.isZooming && !this.isZoomingNow) {\n setLastGestureTime();\n\n this.draggingType = e.type as any;\n const {inBoundsX, inBoundsY} = adjustPosition(xDiff, yDiff);\n cancelDrag?.(!inBoundsX, !inBoundsY);\n\n return;\n }\n\n if(this.isZoomingNow || !IS_TOUCH_SUPPORTED) {\n return;\n }\n\n const percents = Math.abs(xDiff) / windowSize.width;\n if(percents > .2 || Math.abs(xDiff) > 125) {\n if(xDiff > 0) {\n this.buttons.prev.click();\n } else {\n this.buttons.next.click();\n }\n\n return true;\n }\n\n const percentsY = Math.abs(yDiff) / windowSize.height;\n if(percentsY > .2 || Math.abs(yDiff) > 125) {\n this.close();\n return true;\n }\n\n return false;\n },\n onZoom: this.onZoom,\n onDoubleClick: ({centerX, centerY}) => {\n if(this.isZooming) {\n this.resetZoom();\n } else {\n const scale = ZOOM_INITIAL_VALUE + 2;\n this.changeZoomByPosition(centerX, centerY, scale);\n }\n },\n verifyTouchTarget: (e) => {\n // * Fix for seek input\n if(isFullScreen() ||\n findUpAsChild(e.target as HTMLElement, this.zoomElements.container) ||\n findUpClassName(e.target, 'ckin__controls') ||\n findUpClassName(e.target, 'media-viewer-caption') ||\n (findUpClassName(e.target, 'media-viewer-topbar') && e.type !== 'wheel')) {\n return false;\n }\n\n return true;\n },\n cursor: ''\n // cursor: 'move'\n });\n }\n\n protected onSwipeFirst = (e?: MouseEvent | TouchEvent | WheelEvent) => {\n this.lastDragOffset = this.lastDragDelta = {x: 0, y: 0};\n this.lastTransform = {...this.transform};\n if(e?.type !== 'wheel' || !this.ctrlKeyDown) { // keep transition for real mouse wheel\n this.moversContainer.classList.add('no-transition');\n this.zoomElements.rangeSelector.container.classList.remove('with-transition');\n }\n this.isGesturingNow = true;\n this.lastGestureTime = Date.now();\n this.clampZoomDebounced.clearTimeout();\n\n if(!this.lastTransform.x && !this.lastTransform.y && !this.isZooming) {\n this.initialContentRect = this.content.media.getBoundingClientRect();\n }\n };\n\n protected onSwipeReset = (e?: Event) => {\n // move\n this.moversContainer.classList.remove('no-transition');\n this.zoomElements.rangeSelector.container.classList.add('with-transition');\n this.clampZoomDebounced.clearTimeout();\n\n if(e?.type === 'mouseup' && this.draggingType === 'mousemove') {\n this.ignoreNextClick = true;\n }\n\n const {draggingType} = this;\n this.isZoomingNow = false;\n this.isGesturingNow = false;\n this.draggingType = undefined;\n\n if(this.closing) {\n return;\n }\n\n if(this.transform.scale > ZOOM_INITIAL_VALUE) {\n // Get current content boundaries\n const s1 = Math.min(this.transform.scale, ZOOM_MAX_VALUE);\n const scaleFactor = s1 / this.transform.scale;\n\n // Calculate new position based on the last zoom center to keep the zoom center\n // at the same position when bouncing back from max zoom\n let x1 = this.transform.x * scaleFactor + (this.lastZoomCenter.x - scaleFactor * this.lastZoomCenter.x);\n let y1 = this.transform.y * scaleFactor + (this.lastZoomCenter.y - scaleFactor * this.lastZoomCenter.y);\n\n // If scale didn't change, we need to add inertia to pan gesture\n if(draggingType && draggingType !== 'wheel' && this.lastTransform.scale === this.transform.scale) {\n // Arbitrary pan velocity coefficient\n const k = 0.1;\n\n // Calculate user gesture velocity\n const elapsedTime = Math.max(1, Date.now() - this.lastGestureTime);\n const Vx = Math.abs(this.lastDragOffset.x) / elapsedTime;\n const Vy = Math.abs(this.lastDragOffset.y) / elapsedTime;\n\n // Add extra distance based on gesture velocity and last pan delta\n x1 -= Math.abs(this.lastDragOffset.x) * Vx * k * -this.lastDragDelta.x;\n y1 -= Math.abs(this.lastDragOffset.y) * Vy * k * -this.lastDragDelta.y;\n }\n\n const [transform] = this.calculateOffsetBoundaries({x: x1, y: y1, scale: s1});\n this.lastTransform = transform;\n this.setTransform(transform);\n } else if(this.transform.scale < ZOOM_INITIAL_VALUE) {\n this.resetZoom();\n }\n };\n\n protected onZoom = ({\n initialCenterX,\n initialCenterY,\n zoom,\n zoomAdd,\n currentCenterX,\n currentCenterY,\n dragOffsetX,\n dragOffsetY,\n zoomFactor\n }: ZoomDetails) => {\n initialCenterX ||= windowSize.width / 2;\n initialCenterY ||= windowSize.height / 2;\n currentCenterX ||= windowSize.width / 2;\n currentCenterY ||= windowSize.height / 2;\n\n this.isZoomingNow = true;\n\n const zoomMaxBounceValue = ZOOM_MAX_VALUE * 3;\n const scale = zoomAdd !== undefined ? clamp(this.lastTransform.scale + zoomAdd, ZOOM_MIN_VALUE, zoomMaxBounceValue) : (zoom ?? clamp(this.lastTransform.scale * zoomFactor, ZOOM_MIN_VALUE, zoomMaxBounceValue));\n const scaleFactor = scale / this.lastTransform.scale;\n const offsetX = Math.abs(Math.min(this.lastTransform.x, 0));\n const offsetY = Math.abs(Math.min(this.lastTransform.y, 0));\n\n // Save last zoom center for bounce back effect\n this.lastZoomCenter = {\n x: currentCenterX,\n y: currentCenterY\n };\n\n // Calculate new center relative to the shifted image\n const scaledCenterX = offsetX + initialCenterX;\n const scaledCenterY = offsetY + initialCenterY;\n\n const {scaleOffsetX, scaleOffsetY} = this.calculateScaleOffset({x: scaledCenterX, y: scaledCenterY, scale: scaleFactor});\n\n const [transform] = this.calculateOffsetBoundaries({\n x: this.lastTransform.x + scaleOffsetX + dragOffsetX,\n y: this.lastTransform.y + scaleOffsetY + dragOffsetY,\n scale\n });\n\n this.setTransform(transform);\n };\n\n protected changeZoomByPosition(x: number, y: number, scale: number) {\n const {scaleOffsetX, scaleOffsetY} = this.calculateScaleOffset({x, y, scale});\n const transform = this.calculateOffsetBoundaries({\n x: scaleOffsetX,\n y: scaleOffsetY,\n scale\n })[0];\n\n this.setTransform(transform);\n }\n\n protected setTransform(transform: Transform) {\n this.transform = transform;\n this.changeZoom(transform.scale);\n }\n\n // Calculate how much we need to shift the image to keep the zoom center at the same position\n protected calculateScaleOffset({x, y, scale}: {\n x: number,\n y: number,\n scale: number\n }) {\n return {\n scaleOffsetX: x - scale * x,\n scaleOffsetY: y - scale * y\n };\n }\n\n protected toggleZoom(enable?: boolean) {\n const isVisible = this.isZooming;\n const auto = enable === undefined;\n if(this.zoomElements.rangeSelector.mousedown || this.ctrlKeyDown) {\n enable = true;\n }\n\n enable ??= !isVisible;\n\n if(isVisible === enable) {\n return;\n }\n\n this.buttons.zoom.classList.toggle('zoom-in', !enable);\n this.zoomElements.container.classList.toggle('is-visible', this.isZooming = enable);\n this.wholeDiv.classList.toggle('is-zooming', enable);\n\n if(auto || !enable) {\n const zoomValue = enable ? this.transform.scale : ZOOM_INITIAL_VALUE;\n this.setZoomValue(zoomValue);\n this.zoomElements.rangeSelector.setProgress(zoomValue);\n }\n\n if(this.videoPlayer) {\n this.videoPlayer.lockControls(enable ? false : undefined);\n }\n }\n\n protected addZoomStep(add: boolean) {\n this.addZoom(ZOOM_STEP * (add ? 1 : -1));\n }\n\n protected resetZoom() {\n this.setTransform({\n x: 0,\n y: 0,\n scale: ZOOM_INITIAL_VALUE\n });\n }\n\n protected changeZoom(value = this.transform.scale) {\n this.transform.scale = value;\n this.zoomElements.rangeSelector.setProgress(value);\n this.setZoomValue(value);\n }\n\n protected addZoom(value: number) {\n this.lastTransform = this.transform;\n this.onZoom({\n zoomAdd: value,\n currentCenterX: 0,\n currentCenterY: 0,\n initialCenterX: 0,\n initialCenterY: 0,\n dragOffsetX: 0,\n dragOffsetY: 0\n });\n this.lastTransform = this.transform;\n this.clampZoomDebounced();\n }\n\n protected getZoomBounce() {\n return this.isGesturingNow && IS_TOUCH_SUPPORTED ? 50 : 0;\n }\n\n protected calculateOffsetBoundaries = (\n {x, y, scale}: Transform,\n offsetTop = 0\n ): [Transform, boolean, boolean] => {\n if(!this.initialContentRect) return [{x, y, scale}, true, true];\n // Get current content boundaries\n let inBoundsX = true;\n let inBoundsY = true;\n\n const {minX, maxX, minY, maxY} = this.getZoomBoundaries(scale, offsetTop);\n\n inBoundsX = isBetween(x, maxX, minX);\n x = clamp(x, maxX, minX);\n\n inBoundsY = isBetween(y, maxY, minY);\n y = clamp(y, maxY, minY);\n\n return [{x, y, scale}, inBoundsX, inBoundsY];\n };\n\n protected getZoomBoundaries(scale = this.transform.scale, offsetTop = 0) {\n if(!this.initialContentRect) {\n return {minX: 0, maxX: 0, minY: 0, maxY: 0};\n }\n\n const centerX = (windowSize.width - windowSize.width * scale) / 2;\n const centerY = (windowSize.height - windowSize.height * scale) / 2;\n\n // If content is outside window we calculate offset boundaries\n // based on initial content rect and current scale\n const minX = Math.max(-this.initialContentRect.left * scale, centerX);\n const maxX = windowSize.width - this.initialContentRect.right * scale;\n\n const minY = Math.max(-this.initialContentRect.top * scale + offsetTop, centerY);\n const maxY = windowSize.height - this.initialContentRect.bottom * scale;\n\n return {minX, maxX, minY, maxY};\n }\n\n protected setZoomValue = (value = this.transform.scale) => {\n this.initialContentRect ??= this.content.media.getBoundingClientRect();\n\n // this.zoomValue = value;\n if(value === ZOOM_INITIAL_VALUE) {\n this.transform.x = 0;\n this.transform.y = 0;\n }\n\n this.moversContainer.style.transform = `translate3d(${this.transform.x.toFixed(3)}px, ${this.transform.y.toFixed(3)}px, 0px) scale(${value.toFixed(3)})`;\n\n this.zoomElements.btnOut.classList.toggle('inactive', value <= ZOOM_MIN_VALUE);\n this.zoomElements.btnIn.classList.toggle('inactive', value >= ZOOM_MAX_VALUE);\n\n this.toggleZoom(value !== ZOOM_INITIAL_VALUE);\n };\n\n protected setBtnMenuToggle(buttons: ButtonMenuItemOptions[]) {\n const btnMenuToggle = ButtonMenuToggle({buttonOptions: {onlyMobile: true}, direction: 'bottom-left', buttons});\n this.topbar.append(btnMenuToggle);\n }\n\n public close(e?: MouseEvent) {\n if(e) {\n cancelEvent(e);\n }\n\n if(this.setMoverAnimationPromise) return Promise.reject();\n\n this.closing = true;\n this.swipeHandler?.removeListeners();\n\n if(this.navigationItem) {\n appNavigationController.removeItem(this.navigationItem);\n }\n\n this.lazyLoadQueue.clear();\n\n const promise = this.setMoverToTarget(this.target?.element, true).then(({onAnimationEnd}) => onAnimationEnd);\n\n this.listLoader.reset();\n (this.listLoader as SearchListLoader<any>).cleanup && (this.listLoader as SearchListLoader<any>).cleanup();\n this.setMoverPromise = null;\n this.tempId = -1;\n if((window as any).appMediaViewer === this) {\n (window as any).appMediaViewer = undefined;\n }\n\n /* if(appSidebarRight.historyTabIDs.slice(-1)[0] === AppSidebarRight.SLIDERITEMSIDS.forward) {\n promise.then(() => {\n appSidebarRight.forwardTab.closeBtn.click();\n });\n } */\n\n this.removeGlobalListeners();\n\n promise.finally(() => {\n this.wholeDiv.remove();\n this.toggleOverlay(false);\n });\n\n return promise;\n }\n\n protected toggleOverlay(active: boolean) {\n overlayCounter.isOverlayActive = active;\n animationIntersector.checkAnimations2(active);\n }\n\n protected toggleGlobalListeners(active: boolean) {\n if(active) this.setGlobalListeners();\n else this.removeGlobalListeners();\n }\n\n protected removeGlobalListeners() {\n window.removeEventListener('keydown', this.onKeyDown);\n window.removeEventListener('keyup', this.onKeyUp);\n }\n\n protected setGlobalListeners() {\n window.addEventListener('keydown', this.onKeyDown);\n window.addEventListener('keyup', this.onKeyUp);\n }\n\n public setMediaTimestamp(timestamp: number) {\n this.videoPlayer?.setTimestamp(timestamp);\n }\n\n onClick = (e: MouseEvent) => {\n if(this.ignoreNextClick) {\n this.ignoreNextClick = undefined;\n return;\n }\n\n if(this.setMoverAnimationPromise) return;\n\n const target = e.target as HTMLElement;\n if(target.tagName === 'A') return;\n cancelEvent(e);\n\n if(IS_TOUCH_SUPPORTED) {\n if(this.highlightSwitchersTimeout) {\n clearTimeout(this.highlightSwitchersTimeout);\n } else {\n this.wholeDiv.classList.add('highlight-switchers');\n }\n\n this.highlightSwitchersTimeout = window.setTimeout(() => {\n this.wholeDiv.classList.remove('highlight-switchers');\n this.highlightSwitchersTimeout = 0;\n }, 3e3);\n\n return;\n }\n\n if(hasMouseMovedSinceDown(e)) {\n return;\n }\n\n const isZooming = this.isZooming && false;\n let mover: HTMLElement = null;\n const classNames = ['ckin__player', 'media-viewer-buttons', 'media-viewer-author', 'media-viewer-caption', 'zoom-container'];\n if(isZooming) {\n classNames.push('media-viewer-movers');\n }\n\n classNames.find((s) => {\n try {\n mover = findUpClassName(target, s);\n if(mover) return true;\n } catch(err) {return false;}\n });\n\n if(/* target === this.mediaViewerDiv */!mover || (!isZooming && (target.tagName === 'IMG' || target.tagName === 'image'))) {\n this.close();\n }\n };\n\n private onKeyDown = (e: KeyboardEvent) => {\n // this.log('onKeyDown', e);\n if(overlayCounter.overlaysActive > 1) {\n return;\n }\n\n const key = e.key;\n\n let good = true;\n if(key === 'ArrowRight') {\n !this.isZooming && this.buttons.next.click();\n } else if(key === 'ArrowLeft') {\n !this.isZooming && this.buttons.prev.click();\n } else if(key === '-' || key === '=') {\n if(this.ctrlKeyDown) {\n this.addZoomStep(key === '=');\n }\n } else {\n good = false;\n }\n\n if(e.ctrlKey || e.metaKey) {\n this.ctrlKeyDown = true;\n }\n\n if(good) {\n cancelEvent(e);\n }\n };\n\n private onKeyUp = (e: KeyboardEvent) => {\n if(overlayCounter.overlaysActive > 1) {\n return;\n }\n\n if(!(e.ctrlKey || e.metaKey)) {\n this.ctrlKeyDown = false;\n\n if(this.isZooming) {\n this.setZoomValue();\n }\n }\n };\n\n protected async setMoverToTarget(target: HTMLElement, closing = false, fromRight = 0) {\n this.dispatchEvent('setMoverBefore');\n\n const mover = this.content.mover;\n\n if(!closing) {\n mover.replaceChildren();\n // mover.append(this.buttons.prev, this.buttons.next);\n }\n\n const zoomValue = this.isZooming && closing /* && false */ ? this.transform.scale : ZOOM_INITIAL_VALUE;\n /* if(!(zoomValue > 1 && closing)) */ this.removeCenterFromMover(mover);\n\n const wasActive = fromRight !== 0;\n\n const delay = liteMode.isAvailable('animations') ? (wasActive ? 350 : 200) : 0;\n // let delay = wasActive ? 350 : 10000;\n\n /* if(wasActive) {\n this.moveTheMover(mover);\n mover = this.setNewMover();\n } */\n\n /* if(DEBUG) {\n this.log('setMoverToTarget', target, closing, wasActive, fromRight);\n } */\n\n let realParent: HTMLElement;\n\n let rect: DOMRect;\n if(target) {\n if(target instanceof AvatarElement || target.classList.contains('grid-item')/* || target.classList.contains('document-ico') */) {\n realParent = target;\n rect = target.getBoundingClientRect();\n } else if(target instanceof SVGImageElement || target.parentElement instanceof SVGForeignObjectElement) {\n realParent = findUpClassName(target, 'attachment');\n rect = realParent.getBoundingClientRect();\n } else if(target.classList.contains('profile-avatars-avatar')) {\n realParent = findUpClassName(target, 'profile-avatars-container');\n rect = realParent.getBoundingClientRect();\n\n // * if not active avatar\n if(closing && target.getBoundingClientRect().left !== rect.left) {\n target = realParent = rect = undefined;\n }\n }\n }\n\n if(!target) {\n target = this.content.media;\n }\n\n if(!rect) {\n realParent = target.parentElement as HTMLElement;\n rect = target.getBoundingClientRect();\n }\n\n let needOpacity = false;\n if(target !== this.content.media && !target.classList.contains('profile-avatars-avatar')) {\n const overflowElement = findUpClassName(realParent, 'scrollable');\n const visibleRect = getVisibleRect(realParent, overflowElement, true);\n\n if(closing && (!visibleRect || visibleRect.overflow.vertical === 2 || visibleRect.overflow.horizontal === 2)) {\n target = this.content.media;\n realParent = target.parentElement as HTMLElement;\n rect = target.getBoundingClientRect();\n } else if(visibleRect && (visibleRect.overflow.vertical === 1 || visibleRect.overflow.horizontal === 1)) {\n needOpacity = true;\n }\n }\n\n const containerRect = this.content.media.getBoundingClientRect();\n\n let transform = '';\n let left: number;\n let top: number;\n\n if(wasActive) {\n left = fromRight === 1 ? windowSize.width : -containerRect.width;\n top = containerRect.top;\n } else {\n left = rect.left;\n top = rect.top;\n }\n\n /* if(zoomValue > 1) { // 33\n // const diffX = (rect.width * zoomValue - rect.width) / 4;\n const diffX = (rect.width * zoomValue - rect.width) / 2;\n const diffY = (rect.height * zoomValue - rect.height) / 4;\n // left -= diffX;\n // top += diffY;\n } */\n\n transform += `translate3d(${left}px,${top}px,0) `;\n\n /* if(wasActive) {\n left = fromRight === 1 ? appPhotosManager.windowW / 2 : -(containerRect.width + appPhotosManager.windowW / 2);\n transform += `translate(${left}px,-50%) `;\n } else {\n left = rect.left - (appPhotosManager.windowW / 2);\n top = rect.top - (appPhotosManager.windowH / 2);\n transform += `translate(${left}px,${top}px) `;\n } */\n\n let aspecter: HTMLDivElement;\n if(target instanceof HTMLImageElement || target instanceof HTMLVideoElement || target.tagName === 'DIV') {\n if(mover.firstElementChild && mover.firstElementChild.classList.contains('media-viewer-aspecter')) {\n aspecter = mover.firstElementChild as HTMLDivElement;\n\n const player = aspecter.querySelector('.ckin__player');\n if(player) {\n const video = player.firstElementChild as HTMLVideoElement;\n aspecter.append(video);\n player.remove();\n }\n\n if(!aspecter.style.cssText) { // всё из-за видео, элементы управления скейлятся, так бы можно было этого не делать\n mover.classList.remove('active');\n this.setFullAspect(aspecter, containerRect, rect);\n void mover.offsetLeft; // reflow\n mover.classList.add('active');\n }\n } else {\n aspecter = document.createElement('div');\n aspecter.classList.add('media-viewer-aspecter'/* , 'disable-hover' */);\n mover.prepend(aspecter);\n }\n\n aspecter.style.cssText = `width: ${rect.width}px; height: ${rect.height}px; transform: scale3d(${containerRect.width / rect.width}, ${containerRect.height / rect.height}, 1);`;\n }\n\n mover.style.width = containerRect.width + 'px';\n mover.style.height = containerRect.height + 'px';\n\n // const scaleX = rect.width / (containerRect.width * zoomValue);\n // const scaleY = rect.height / (containerRect.height * zoomValue);\n const scaleX = rect.width / containerRect.width;\n const scaleY = rect.height / containerRect.height;\n if(!wasActive) {\n transform += `scale3d(${scaleX},${scaleY},1) `;\n }\n\n let borderRadius = window.getComputedStyle(realParent).getPropertyValue('border-radius');\n const brSplitted = fillPropertyValue(borderRadius) as string[];\n borderRadius = brSplitted.map((r) => (parseInt(r) / scaleX) + 'px').join(' ');\n if(!wasActive) {\n mover.style.borderRadius = borderRadius;\n }\n // let borderRadius = '0px 0px 0px 0px';\n\n if(closing && zoomValue !== 1) {\n const left = rect.left - (windowSize.width * scaleX - rect.width) / 2;\n const top = rect.top - (windowSize.height * scaleY - rect.height) / 2;\n this.moversContainer.style.transform = `matrix(${scaleX}, 0, 0, ${scaleY}, ${left}, ${top})`;\n } else {\n mover.style.transform = transform;\n }\n\n needOpacity && (mover.style.opacity = '0'/* !closing ? '0' : '' */);\n\n /* if(wasActive) {\n this.log('setMoverToTarget', mover.style.transform);\n } */\n\n let path: SVGPathElement;\n const isOut = target.classList.contains('is-out');\n\n const deferred = this.setMoverAnimationPromise = deferredPromise<void>();\n const ret = {onAnimationEnd: deferred};\n\n const timeout = setTimeout(() => {\n if(!deferred.isFulfilled && !deferred.isRejected) {\n deferred.resolve();\n }\n }, 1000);\n\n deferred.finally(() => {\n this.dispatchEvent('setMoverAfter');\n\n if(this.setMoverAnimationPromise === deferred) {\n this.setMoverAnimationPromise = null;\n }\n\n clearTimeout(timeout);\n });\n\n if(!closing) {\n let mediaElement: HTMLImageElement | HTMLVideoElement | HTMLCanvasElement;\n let src: string;\n\n // if(target instanceof HTMLVideoElement) {\n const selector = 'video, img, .canvas-thumbnail';\n const queryFrom = target.matches(selector) ? target.parentElement : target;\n const elements = Array.from(queryFrom.querySelectorAll(selector)) as HTMLImageElement[];\n if(elements.length) {\n target = elements.pop();\n const canvas = document.createElement('canvas');\n const context = canvas.getContext('2d');\n if(target instanceof HTMLImageElement) {\n canvas.width = target.naturalWidth;\n canvas.height = target.naturalHeight;\n } else if(target instanceof HTMLVideoElement) {\n canvas.width = target.videoWidth;\n canvas.height = target.videoHeight;\n } else if(target instanceof HTMLCanvasElement) {\n canvas.width = target.width;\n canvas.height = target.height;\n }\n\n canvas.className = 'canvas-thumbnail thumbnail media-photo';\n context.drawImage(target as HTMLImageElement | HTMLCanvasElement, 0, 0);\n target = canvas;\n }\n // }\n\n if(target.tagName === 'DIV' || target.tagName === 'AVATAR-ELEMENT') { // useContainerAsTarget\n const images = Array.from(target.querySelectorAll('img')) as HTMLImageElement[];\n const image = images.pop();\n if(image) {\n mediaElement = new Image();\n src = image.src;\n mover.append(mediaElement);\n }\n /* mediaElement = new Image();\n src = target.style.backgroundImage.slice(5, -2); */\n } else if(target instanceof HTMLImageElement) {\n mediaElement = new Image();\n src = target.src;\n } else if(target instanceof HTMLVideoElement) {\n mediaElement = createVideo();\n mediaElement.src = target.src;\n } else if(target instanceof SVGSVGElement) {\n const clipId = target.dataset.clipId;\n const newClipId = clipId + '-mv';\n\n const {width, height} = containerRect;\n\n const newSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n newSvg.setAttributeNS(null, 'width', '' + width);\n newSvg.setAttributeNS(null, 'height', '' + height);\n\n // нижние два свойства для масштабирования\n newSvg.setAttributeNS(null, 'viewBox', `0 0 ${width} ${height}`);\n newSvg.setAttributeNS(null, 'preserveAspectRatio', 'xMidYMid meet');\n\n newSvg.insertAdjacentHTML('beforeend', target.firstElementChild.outerHTML.replace(clipId, newClipId));\n newSvg.insertAdjacentHTML('beforeend', target.lastElementChild.outerHTML.replace(clipId, newClipId));\n\n // теперь надо выставить новую позицию для хвостика\n const defs = newSvg.firstElementChild;\n const use = defs.firstElementChild.firstElementChild as SVGUseElement;\n if(use instanceof SVGUseElement) {\n let transform = use.getAttributeNS(null, 'transform');\n transform = transform.replace(/translate\\((.+?), (.+?)\\) scale\\((.+?), (.+?)\\)/, (match, x, y, sX, sY) => {\n x = +x;\n if(x !== 2) {\n x = width - (2 / scaleX);\n } else {\n x = 2 / scaleX;\n }\n\n y = height;\n\n return `translate(${x}, ${y}) scale(${+sX / scaleX}, ${+sY / scaleY})`;\n });\n use.setAttributeNS(null, 'transform', transform);\n\n // и новый RECT\n path = defs.firstElementChild.lastElementChild as SVGPathElement;\n\n // код ниже нужен только чтобы скрыть моргание до момента как сработает таймаут\n let d: string;\n const br: [number, number, number, number] = borderRadius.split(' ').map((v) => parseInt(v)) as any;\n if(isOut) d = generatePathData(0, 0, width - 9 / scaleX, height, ...br);\n else d = generatePathData(9 / scaleX, 0, width - 9 / scaleX, height, ...br);\n path.setAttributeNS(null, 'd', d);\n }\n\n const foreignObject = newSvg.lastElementChild;\n foreignObject.setAttributeNS(null, 'width', '' + containerRect.width);\n foreignObject.setAttributeNS(null, 'height', '' + containerRect.height);\n\n mover.prepend(newSvg);\n } else if(target instanceof HTMLCanvasElement) {\n mediaElement = target;\n }\n\n if(aspecter) {\n aspecter.style.borderRadius = borderRadius;\n\n if(mediaElement) {\n aspecter.append(mediaElement);\n }\n }\n\n mediaElement = mover.querySelector('video, img');\n if(mediaElement instanceof HTMLImageElement) {\n mediaElement.classList.add('thumbnail');\n if(!aspecter) {\n mediaElement.style.width = containerRect.width + 'px';\n mediaElement.style.height = containerRect.height + 'px';\n }\n\n if(src) {\n await renderImageFromUrlPromise(mediaElement, src);\n }\n }/* else if(mediaElement instanceof HTMLVideoElement && mediaElement.firstElementChild && ((mediaElement.firstElementChild as HTMLSourceElement).src || src)) {\n await new Promise((resolve, reject) => {\n mediaElement.addEventListener('loadeddata', resolve);\n\n if(src) {\n (mediaElement.firstElementChild as HTMLSourceElement).src = src;\n }\n });\n } */\n\n mover.style.display = '';\n\n fastRaf(() => {\n mover.classList.add(wasActive ? 'moving' : 'active');\n });\n } else {\n /* if(mover.classList.contains('center')) {\n mover.classList.remove('center');\n void mover.offsetLeft; // reflow\n } */\n\n if(target instanceof SVGSVGElement) {\n path = mover.querySelector('path');\n\n if(path) {\n this.sizeTailPath(path, containerRect, scaleX, delay, false, isOut, borderRadius);\n }\n }\n\n if(target.classList.contains('media-viewer-media')) {\n mover.classList.add('hiding');\n }\n\n this.toggleWholeActive(false);\n\n // return ret;\n\n setTimeout(() => {\n mover.style.borderRadius = borderRadius;\n\n if(mover.firstElementChild) {\n (mover.firstElementChild as HTMLElement).style.borderRadius = borderRadius;\n }\n }, delay / 2);\n\n setTimeout(() => {\n mover.replaceChildren();\n mover.classList.remove('moving', 'active', 'hiding');\n mover.style.cssText = 'display: none;';\n\n deferred.resolve();\n }, delay);\n\n mover.classList.remove('opening');\n\n return ret;\n }\n\n mover.classList.add('opening');\n\n // await new Promise((resolve) => setTimeout(resolve, 0));\n // await new Promise((resolve) => window.requestAnimationFrame(resolve));\n // * одного RAF'а недостаточно, иногда анимация с одним не срабатывает (преимущественно на мобильных)\n await doubleRaf();\n\n // чтобы проверить установленную позицию - раскомментировать\n // throw '';\n\n // await new Promise((resolve) => setTimeout(resolve, 5e3));\n\n mover.style.transform = `translate3d(${containerRect.left}px,${containerRect.top}px,0) scale3d(1,1,1)`;\n // mover.style.transform = `translate(-50%,-50%) scale(1,1)`;\n needOpacity && (mover.style.opacity = ''/* closing ? '0' : '' */);\n\n if(aspecter) {\n this.setFullAspect(aspecter, containerRect, rect);\n }\n\n // throw '';\n\n setTimeout(() => {\n mover.style.borderRadius = '';\n\n if(mover.firstElementChild) {\n (mover.firstElementChild as HTMLElement).style.borderRadius = '';\n }\n }, 0/* delay / 2 */);\n\n mover.dataset.timeout = '' + setTimeout(() => {\n mover.classList.remove('moving', 'opening');\n\n if(aspecter) { // всё из-за видео, элементы управления скейлятся, так бы можно было этого не делать\n if(mover.querySelector('video') || true) {\n mover.classList.remove('active');\n aspecter.style.cssText = '';\n void mover.offsetLeft; // reflow\n }\n\n // aspecter.classList.remove('disable-hover');\n }\n\n // эти строки нужны для установки центральной позиции, в случае ресайза это будет нужно\n mover.classList.add('center', 'no-transition');\n /* mover.style.left = mover.style.top = '50%';\n mover.style.transform = 'translate(-50%, -50%)';\n void mover.offsetLeft; // reflow */\n\n // это уже нужно для будущих анимаций\n mover.classList.add('active');\n delete mover.dataset.timeout;\n\n deferred.resolve();\n }, delay);\n\n if(path) {\n this.sizeTailPath(path, containerRect, scaleX, delay, true, isOut, borderRadius);\n }\n\n return ret;\n }\n\n protected toggleWholeActive(active: boolean) {\n if(active) {\n this.wholeDiv.classList.add('active');\n } else {\n this.wholeDiv.classList.add('backwards');\n setTimeout(() => {\n this.wholeDiv.classList.remove('active');\n }, 0);\n }\n }\n\n protected setFullAspect(aspecter: HTMLDivElement, containerRect: DOMRect, rect: DOMRect) {\n /* let media = aspecter.firstElementChild;\n let proportion: number;\n if(media instanceof HTMLImageElement) {\n proportion = media.naturalWidth / media.naturalHeight;\n } else if(media instanceof HTMLVideoElement) {\n proportion = media.videoWidth / media.videoHeight;\n } */\n const proportion = containerRect.width / containerRect.height;\n\n let {width, height} = rect;\n /* if(proportion === 1) {\n aspecter.style.cssText = '';\n } else { */\n if(proportion > 0) {\n width = height * proportion;\n } else {\n height = width * proportion;\n }\n\n // this.log('will set style aspecter:', `width: ${width}px; height: ${height}px; transform: scale(${containerRect.width / width}, ${containerRect.height / height});`);\n\n aspecter.style.cssText = `width: ${width}px; height: ${height}px; transform: scale3d(${containerRect.width / width}, ${containerRect.height / height}, 1);`;\n // }\n }\n\n protected sizeTailPath(path: SVGPathElement, rect: DOMRect, scaleX: number, delay: number, upscale: boolean, isOut: boolean, borderRadius: string) {\n const start = Date.now();\n const {width, height} = rect;\n delay = delay / 2;\n\n const br = borderRadius.split(' ').map((v) => parseInt(v));\n\n const step = () => {\n const diff = Date.now() - start;\n\n let progress = delay ? diff / delay : 1;\n if(progress > 1) progress = 1;\n if(upscale) progress = 1 - progress;\n\n const _br: [number, number, number, number] = br.map((v) => v * progress) as any;\n\n let d: string;\n if(isOut) d = generatePathData(0, 0, width - (9 / scaleX * progress), height, ..._br);\n else d = generatePathData(9 / scaleX * progress, 0, width/* width - (9 / scaleX * progress) */, height, ..._br);\n path.setAttributeNS(null, 'd', d);\n\n if(diff < delay) fastRaf(step);\n };\n\n // window.requestAnimationFrame(step);\n step();\n }\n\n protected removeCenterFromMover(mover: HTMLElement) {\n if(mover.classList.contains('center')) {\n // const rect = mover.getBoundingClientRect();\n const rect = this.content.media.getBoundingClientRect();\n mover.style.transform = `translate3d(${rect.left}px,${rect.top}px,0)`;\n mover.classList.remove('center');\n void mover.offsetLeft; // reflow\n mover.classList.remove('no-transition');\n }\n }\n\n protected moveTheMover(mover: HTMLElement, toLeft = true) {\n const windowW = windowSize.width;\n\n this.removeCenterFromMover(mover);\n\n // mover.classList.remove('active');\n mover.classList.add('moving');\n\n if(mover.dataset.timeout) { // и это тоже всё из-за скейла видео, так бы это не нужно было\n clearTimeout(+mover.dataset.timeout);\n }\n\n const rect = mover.getBoundingClientRect();\n\n const newTransform = mover.style.transform.replace(/translate3d\\((.+?),/, (match, p1) => {\n const x = toLeft ? -rect.width : windowW;\n // const x = toLeft ? -(rect.right + (rect.width / 2)) : windowW / 2;\n\n return match.replace(p1, x + 'px');\n });\n\n // //////this.log('set newTransform:', newTransform, mover.style.transform, toLeft);\n mover.style.transform = newTransform;\n\n setTimeout(() => {\n mover.remove();\n }, 350);\n }\n\n protected setNewMover() {\n const newMover = document.createElement('div');\n newMover.classList.add('media-viewer-mover');\n newMover.style.display = 'none';\n\n if(this.content.mover) {\n const oldMover = this.content.mover;\n oldMover.parentElement.append(newMover);\n } else {\n this.moversContainer.append(newMover);\n }\n\n return this.content.mover = newMover;\n }\n\n protected updateMediaSource(target: HTMLElement, url: string, tagName: 'video' | 'img') {\n // if(target instanceof SVGSVGElement) {\n const el = target.tagName.toLowerCase() === tagName ? target : target.querySelector(tagName) as HTMLElement;\n if(el && !findUpClassName(target, 'document')) {\n if(findUpClassName(target, 'attachment')) {\n // two parentElements because element can be contained in aspecter\n const preloader = target.parentElement.parentElement.querySelector('.preloader-container') as HTMLElement;\n if(preloader) {\n if(tagName === 'video') {\n if(preloader.classList.contains('manual')) {\n preloader.click();\n // return;\n }\n\n return;\n }\n\n preloader.remove();\n }\n }\n\n if((el as HTMLImageElement).src !== url) {\n renderImageFromUrl(el, url);\n }\n\n // ! костыль, но он тут даже и не нужен\n if(el.classList.contains('thumbnail') && el.parentElement.classList.contains('media-container-aspecter')) {\n el.classList.remove('thumbnail');\n }\n }\n /* } else {\n\n } */\n }\n\n protected setAuthorInfo(fromId: PeerId | string, timestamp: number) {\n const isPeerId = fromId.isPeerId();\n let wrapTitlePromise: Promise<HTMLElement> | HTMLElement;\n if(isPeerId) {\n wrapTitlePromise = wrapPeerTitle({\n peerId: fromId as PeerId,\n dialog: false,\n onlyFirstName: false,\n plainText: false\n })\n } else {\n const title = wrapTitlePromise = document.createElement('span');\n title.append(wrapEmojiText(fromId));\n title.classList.add('peer-title');\n }\n\n const oldAvatar = this.author.avatarEl;\n const newAvatar = this.author.avatarEl = (oldAvatar.cloneNode() as AvatarElement);\n\n return Promise.all([\n (this.author.avatarEl as AvatarElement).updateWithOptions({\n peerId: fromId as PeerId || NULL_PEER_ID,\n peerTitle: isPeerId ? undefined : '' + fromId\n }),\n\n wrapTitlePromise\n ]).then(([_, title]) => {\n if(this.author.avatarEl !== newAvatar) {\n return;\n }\n\n replaceContent(this.author.date, formatFullSentTime(timestamp));\n replaceContent(this.author.nameEl, title);\n oldAvatar.replaceWith(this.author.avatarEl);\n });\n }\n\n protected async _openMedia({\n media,\n timestamp,\n fromId,\n fromRight,\n target,\n reverse = false,\n prevTargets = [],\n nextTargets = [],\n message,\n mediaTimestamp\n }: {\n media: MyDocument | MyPhoto,\n timestamp: number,\n fromId: PeerId | string,\n fromRight: number,\n target?: HTMLElement,\n reverse?: boolean,\n prevTargets?: TargetType[],\n nextTargets?: TargetType[],\n message?: MyMessage,\n mediaTimestamp?: number\n /* , needLoadMore = true */\n }) {\n if(this.setMoverPromise) return this.setMoverPromise;\n\n /* if(DEBUG) {\n this.log('openMedia:', media, fromId, prevTargets, nextTargets);\n } */\n\n const setAuthorPromise = this.setAuthorInfo(fromId, timestamp);\n\n const isDocument = media._ === 'document';\n const isVideo = isDocument && media.mime_type && ((['video', 'gif'] as MyDocument['type'][]).includes(media.type) || media.mime_type.indexOf('video/') === 0);\n\n if(this.isFirstOpen) {\n // this.targetContainer = targetContainer;\n // this.needLoadMore = needLoadMore;\n this.isFirstOpen = false;\n this.listLoader.setTargets(prevTargets, nextTargets, reverse);\n (window as any).appMediaViewer = this;\n // this.loadMore = loadMore;\n\n /* if(appSidebarRight.historyTabIDs.slice(-1)[0] === AppSidebarRight.SLIDERITEMSIDS.forward) {\n appSidebarRight.forwardTab.closeBtn.click();\n await new Promise((resolve) => setTimeout(resolve, 200));\n } */\n }\n\n if(this.listLoader.next.length < 10) {\n setTimeout(() => {\n this.listLoader.load(true);\n }, 0);\n }\n\n // if(prevTarget && (!prevTarget.parentElement || !this.isElementVisible(this.targetContainer, prevTarget))) prevTarget = null;\n // if(nextTarget && (!nextTarget.parentElement || !this.isElementVisible(this.targetContainer, nextTarget))) nextTarget = null;\n\n this.buttons.prev.classList.toggle('hide', !this.listLoader.previous.length);\n this.buttons.next.classList.toggle('hide', !this.listLoader.next.length);\n\n const container = this.content.media;\n const useContainerAsTarget = !target || target === container;\n if(useContainerAsTarget) target = container;\n\n this.target = {element: target} as any;\n const tempId = ++this.tempId;\n\n if(container.firstElementChild) {\n container.replaceChildren();\n }\n\n // ok set\n\n const wasActive = fromRight !== 0;\n if(wasActive) {\n this.moveTheMover(this.content.mover, fromRight === 1);\n this.setNewMover();\n } else {\n this.navigationItem = {\n type: 'media',\n onPop: (canAnimate) => {\n if(this.setMoverAnimationPromise) {\n return false;\n }\n\n if(!canAnimate && IS_MOBILE_SAFARI) {\n this.wholeDiv.remove();\n }\n\n this.close();\n }\n };\n\n appNavigationController.pushItem(this.navigationItem);\n\n this.toggleOverlay(true);\n this.setGlobalListeners();\n await setAuthorPromise;\n\n if(!this.wholeDiv.parentElement) {\n this.pageEl.insertBefore(this.wholeDiv, document.getElementById('main-columns'));\n void this.wholeDiv.offsetLeft; // reflow\n }\n\n this.toggleWholeActive(true);\n }\n\n // //////this.log('wasActive:', wasActive);\n\n const mover = this.content.mover;\n\n const maxWidth = windowSize.width;\n // const maxWidth = this.pageEl.scrollWidth;\n // TODO: const maxHeight = mediaSizes.isMobile ? appPhotosManager.windowH : appPhotosManager.windowH - 100;\n let padding = 0;\n const windowH = windowSize.height;\n if(windowH < 1000000 && !mediaSizes.isMobile) {\n padding = 120;\n }\n const maxHeight = windowH - 120 - padding;\n let thumbPromise: Promise<any> = Promise.resolve();\n const size = setAttachmentSize(media, container, maxWidth, maxHeight, mediaSizes.isMobile ? false : true, undefined, !!(isDocument && media.w && media.h)).photoSize;\n if(useContainerAsTarget) {\n const cacheContext = await this.managers.thumbsStorage.getCacheContext(media, size.type);\n let img: HTMLImageElement | HTMLCanvasElement;\n if(cacheContext.downloaded) {\n img = new Image();\n img.src = cacheContext.url;\n } else {\n const gotThumb = getStrippedThumbIfNeeded(media, cacheContext, true);\n if(gotThumb) {\n thumbPromise = gotThumb.loadPromise;\n img = gotThumb.image;\n }\n }\n\n if(img) {\n img.classList.add('thumbnail');\n container.append(img);\n }\n }\n\n // need after setAttachmentSize\n /* if(useContainerAsTarget) {\n target = target.querySelector('img, video') || target;\n } */\n\n const supportsStreaming: boolean = !!(isDocument && media.supportsStreaming);\n const preloader = supportsStreaming ? this.preloaderStreamable : this.preloader;\n\n const getCacheContext = (type = size?.type) => {\n return this.managers.thumbsStorage.getCacheContext(media, type);\n };\n\n let setMoverPromise: Promise<void>;\n if(isVideo) {\n // //////this.log('will wrap video', media, size);\n\n // потому что для safari нужно создать элемент из event'а\n // const video = document.createElement('video');\n const useController = message && media.type !== 'gif';\n const video = /* useController ?\n appMediaPlaybackController.addMedia(message, false, true) as HTMLVideoElement :\n */createVideo({pip: useController});\n\n if(this.wholeDiv.classList.contains('no-forwards')) {\n video.addEventListener('contextmenu', cancelEvent);\n }\n\n const set = () => this.setMoverToTarget(target, false, fromRight).then(({onAnimationEnd}) => {\n // return; // set and don't move\n // if(wasActive) return;\n // return;\n\n const div = mover.firstElementChild && mover.firstElementChild.classList.contains('media-viewer-aspecter') ? mover.firstElementChild : mover;\n // const video = mover.querySelector('video') || document.createElement('video');\n\n const moverVideo = mover.querySelector('video');\n if(moverVideo) {\n moverVideo.remove();\n }\n\n // video.src = '';\n\n video.setAttribute('playsinline', 'true');\n\n // * fix for playing video if viewer is closed (https://contest.com/javascript-web-bonus/entry1425#issue11629)\n video.addEventListener('timeupdate', () => {\n if(this.tempId !== tempId) {\n video.pause();\n }\n });\n\n this.addEventListener('setMoverAfter', () => {\n video.src = '';\n video.load();\n }, {once: true});\n\n if(IS_SAFARI) {\n // test stream\n // video.controls = true;\n video.autoplay = true;\n }\n\n if(media.type === 'gif') {\n video.muted = true;\n video.autoplay = true;\n video.loop = true;\n } else if(media.duration < 60) {\n video.loop = true;\n }\n\n if(mediaTimestamp !== undefined) {\n video.currentTime = mediaTimestamp;\n }\n\n // if(!video.parentElement) {\n div.append(video);\n // }\n\n const canPlayThrough = new Promise((resolve) => {\n video.addEventListener('canplay', resolve, {once: true});\n });\n\n const createPlayer = () => {\n if(media.type !== 'gif') {\n video.dataset.ckin = 'default';\n video.dataset.overlay = '1';\n\n Promise.all([canPlayThrough, onAnimationEnd]).then(() => {\n if(this.tempId !== tempId) {\n return;\n }\n\n // const play = useController ? appMediaPlaybackController.willBePlayedMedia === video : true;\n const play = true;\n const player = this.videoPlayer = new VideoPlayer({\n video,\n play,\n streamable: supportsStreaming,\n onPlaybackRackMenuToggle: (open) => {\n this.wholeDiv.classList.toggle('hide-caption', !!open);\n },\n onPip: (pip) => {\n const otherMediaViewer = (window as any).appMediaViewer;\n if(!pip && otherMediaViewer && otherMediaViewer !== this) {\n this.releaseSingleMedia = undefined;\n this.close();\n return;\n }\n\n const mover = this.moversContainer.lastElementChild as HTMLElement;\n mover.classList.toggle('hiding', pip);\n this.toggleWholeActive(!pip);\n this.toggleOverlay(!pip);\n this.toggleGlobalListeners(!pip);\n\n if(this.navigationItem) {\n if(pip) appNavigationController.removeItem(this.navigationItem);\n else appNavigationController.pushItem(this.navigationItem);\n }\n\n if(useController) {\n if(pip) {\n // appMediaPlaybackController.toggleSwitchers(true);\n\n this.releaseSingleMedia(false);\n this.releaseSingleMedia = undefined;\n\n appMediaPlaybackController.setPictureInPicture(video);\n } else {\n this.releaseSingleMedia = appMediaPlaybackController.setSingleMedia(video, message as Message.message);\n }\n }\n },\n onPipClose: () => {\n // this.target = undefined;\n // this.toggleWholeActive(false);\n // this.toggleOverlay(false);\n this.close();\n }\n });\n player.addEventListener('toggleControls', (show) => {\n this.wholeDiv.classList.toggle('has-video-controls', show);\n });\n\n this.addEventListener('setMoverBefore', () => {\n this.wholeDiv.classList.remove('has-video-controls');\n this.videoPlayer.cleanup();\n this.videoPlayer = undefined;\n }, {once: true});\n\n if(this.isZooming) {\n this.videoPlayer.lockControls(false);\n }\n /* div.append(video);\n mover.append(player.wrapper); */\n });\n }\n };\n\n if(supportsStreaming) {\n onAnimationEnd.then(() => {\n if(video.readyState < video.HAVE_FUTURE_DATA) {\n // console.log('ppp 1');\n preloader.attach(mover, true);\n }\n\n /* canPlayThrough.then(() => {\n preloader.detach();\n }); */\n });\n\n const attachCanPlay = () => {\n video.addEventListener('canplay', () => {\n // console.log('ppp 2');\n preloader.detach();\n video.parentElement.classList.remove('is-buffering');\n }, {once: true});\n };\n\n video.addEventListener('waiting', () => {\n const loading = video.networkState === video.NETWORK_LOADING;\n const isntEnoughData = video.readyState < video.HAVE_FUTURE_DATA;\n\n // this.log('video waiting for progress', loading, isntEnoughData);\n if(loading && isntEnoughData) {\n attachCanPlay();\n\n // console.log('ppp 3');\n preloader.attach(mover, true);\n\n // поставлю класс для плеера, чтобы убрать большую иконку пока прелоадер на месте\n video.parentElement.classList.add('is-buffering');\n }\n });\n\n if(this.wholeDiv.classList.contains('no-forwards')) {\n video.addEventListener('contextmenu', (e) => {\n cancelEvent(e);\n });\n }\n\n attachCanPlay();\n }\n\n // if(!video.src || media.url !== video.src) {\n const load = async() => {\n /* if(useController) {\n appMediaPlaybackController.resolveWaitingForLoadMedia(message.peerId, message.mid, message.pFlags.is_scheduled);\n } */\n\n const promise: Promise<any> = supportsStreaming ? Promise.resolve() : appDownloadManager.downloadMediaURL({media});\n\n if(!supportsStreaming) {\n onAnimationEnd.then(async() => {\n if(!(await getCacheContext()).url) {\n // console.log('ppp 4');\n preloader.attach(mover, true, promise);\n }\n });\n }\n\n Promise.all([promise, onAnimationEnd]).then(async() => {\n if(this.tempId !== tempId) {\n this.log.warn('media viewer changed video');\n return;\n }\n\n const url = (await getCacheContext()).url;\n\n video.addEventListener('error', () => {\n toastNew({\n langPackKey: IS_MOBILE ? 'Video.Unsupported.Mobile' : 'Video.Unsupported.Desktop'\n });\n\n if(video.error.code !== 4) {\n this.log.error('Error ' + video.error.code + '; details: ' + video.error.message);\n }\n\n preloader?.detach();\n }, {once: true});\n\n if(target instanceof SVGSVGElement/* && (video.parentElement || !isSafari) */) { // if video exists\n // if(!video.parentElement) {\n div.firstElementChild.lastElementChild.append(video);\n // }\n } else {\n renderImageFromUrl(video, url);\n }\n\n // * have to set options (especially playbackRate) after src\n // * https://github.com/videojs/video.js/issues/2516\n if(useController) {\n this.releaseSingleMedia = appMediaPlaybackController.setSingleMedia(video, message as Message.message);\n\n this.addEventListener('setMoverBefore', () => {\n if(this.releaseSingleMedia) {\n this.releaseSingleMedia();\n this.releaseSingleMedia = undefined;\n }\n }, {once: true});\n }\n\n this.updateMediaSource(target, url, 'video');\n\n createPlayer();\n });\n\n return promise;\n };\n\n this.lazyLoadQueue.unshift({load});\n // } else createPlayer();\n });\n\n setMoverPromise = thumbPromise.then(set);\n } else {\n const set = () => this.setMoverToTarget(target, false, fromRight).then(({onAnimationEnd}) => {\n // return; // set and don't move\n // if(wasActive) return;\n // return;\n\n const load = async() => {\n const cancellablePromise = isDocument ? appDownloadManager.downloadMediaURL({media}) : appDownloadManager.downloadMediaURL({media, thumb: size});\n\n const photoSizes = !isDocument && media.sizes.slice().filter((size) => (size as PhotoSize.photoSize).w) as PhotoSize.photoSize[];\n photoSizes && photoSizes.sort((a, b) => b.size - a.size);\n const fullPhotoSize = photoSizes?.[0];\n const cancellableFullPromise = !isDocument && fullPhotoSize !== size && appDownloadManager.downloadMediaURL({media, thumb: fullPhotoSize});\n\n onAnimationEnd.then(async() => {\n if(!(await getCacheContext()).url) {\n this.preloader.attachPromise(cancellablePromise);\n // this.preloader.attach(mover, true, cancellablePromise);\n }\n });\n\n Promise.all([onAnimationEnd, cancellablePromise]).then(async() => {\n if(this.tempId !== tempId) {\n this.log.warn('media viewer changed photo');\n return;\n }\n\n const url = (await getCacheContext()).url;\n if(target instanceof SVGSVGElement) {\n this.updateMediaSource(target, url, 'img');\n this.updateMediaSource(mover, url, 'img');\n\n if(mediaSizes.isMobile) {\n const imgs = mover.querySelectorAll('img');\n imgs.forEach((img) => {\n img.classList.remove('thumbnail'); // может здесь это вообще не нужно\n });\n }\n } else {\n const div = mover.firstElementChild && mover.firstElementChild.classList.contains('media-viewer-aspecter') ? mover.firstElementChild : mover;\n const haveImage = ['CANVAS', 'IMG'].includes(div.firstElementChild?.tagName) ? div.firstElementChild as HTMLElement : null;\n if((haveImage as HTMLImageElement)?.src !== url) {\n const image = new Image();\n image.classList.add('thumbnail');\n\n renderImageFromUrl(image, url, () => {\n fastRaf(() => {\n this.updateMediaSource(target, url, 'img');\n\n if(haveImage) {\n fastRaf(() => {\n haveImage.remove();\n });\n }\n\n div.append(image);\n });\n }, false);\n\n cancellableFullPromise && cancellableFullPromise.then((url) => {\n const fullImage = new Image();\n fullImage.classList.add('thumbnail');\n renderImageFromUrl(fullImage, url, () => {\n fastRaf(() => {\n image.replaceWith(fullImage);\n });\n }, false);\n });\n }\n }\n\n // this.preloader.detach();\n }).catch((err) => {\n this.log.error(err);\n this.preloader.attach(mover);\n this.preloader.setManual();\n });\n\n return cancellablePromise;\n };\n\n this.lazyLoadQueue.unshift({load});\n });\n\n setMoverPromise = thumbPromise.then(set);\n }\n\n return this.setMoverPromise = setMoverPromise.catch(() => {\n this.setMoverAnimationPromise = null;\n }).finally(() => {\n this.setMoverPromise = null;\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function fillPropertyValue(str: string) {\n const splitted = str.split(' ');\n if(splitted.length !== 4) {\n if(!splitted[0]) splitted[0] = '0px';\n for(let i = splitted.length; i < 4; ++i) {\n splitted[i] = splitted[i % 2] || splitted[0] || '0px';\n }\n }\n\n return splitted;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport {IS_MOBILE_SAFARI} from '../environment/userAgent';\nimport {logger} from '../lib/logger';\nimport blurActiveElement from '../helpers/dom/blurActiveElement';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport isSwipingBackSafari from '../helpers/dom/isSwipingBackSafari';\nimport indexOfAndSplice from '../helpers/array/indexOfAndSplice';\n\nexport type NavigationItem = {\n type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' |\n 'esg' | 'multiselect' | 'input-helper' | 'autocomplete-helper' | 'markup' |\n 'global-search' | 'voice' | 'mobile-search' | 'filters' | 'global-search-focus' |\n 'toast' | 'dropdown' | 'forum',\n onPop: (canAnimate: boolean) => boolean | void,\n onEscape?: () => boolean,\n noHistory?: boolean,\n noBlurOnPop?: boolean,\n};\n\nexport class AppNavigationController {\n private navigations: Array<NavigationItem>;\n private id: number;\n private manual: boolean;\n private log: ReturnType<typeof logger>;\n private debug: boolean;\n private currentHash: string; // have to start with # if not empty\n private overriddenHash: string; // have to start with # if not empty\n private isPossibleSwipe: boolean;\n public onHashChange: () => void;\n\n constructor() {\n this.navigations = [];\n this.id = Date.now();\n this.manual = false;\n this.log = logger('NC');\n this.debug = true;\n this.currentHash = window.location.hash;\n this.overriddenHash = '';\n this.isPossibleSwipe = false;\n\n window.addEventListener('popstate', this.onPopState);\n window.addEventListener('keydown', this.onKeyDown, {capture: true, passive: false});\n\n if(IS_MOBILE_SAFARI) {\n const options = {passive: true};\n window.addEventListener('touchstart', this.onTouchStart, options);\n }\n\n history.scrollRestoration = 'manual';\n\n this.pushState(); // * push init state\n }\n\n private onPopState = (e: PopStateEvent) => {\n const hash = window.location.hash;\n const id: number = e.state;\n this.debug && this.log('popstate', e, this.isPossibleSwipe, hash);\n if(hash !== this.currentHash) {\n this.debug && this.log.warn(`hash changed, new=${hash}, current=${this.currentHash}, overridden=${this.overriddenHash}`);\n // fix for returning to wrong hash (e.g. chat -> archive -> chat -> 3x back)\n if(id === this.id && this.overriddenHash && this.overriddenHash !== hash) {\n this.overrideHash(this.overriddenHash);\n } else if(id/* === this.id */ && !this.overriddenHash && hash) {\n this.overrideHash();\n } else {\n this.currentHash = hash;\n this.onHashChange && this.onHashChange();\n // this.replaceState();\n return;\n }\n }\n\n if(id !== this.id/* && !this.navigations.length */) {\n this.pushState();\n\n if(!this.navigations.length) {\n return;\n }\n }\n\n const item = this.navigations.pop();\n if(!item) {\n this.pushState();\n return;\n }\n\n this.manual = !this.isPossibleSwipe;\n this.handleItem(item);\n // this.pushState(); // * prevent adding forward arrow\n };\n\n private onKeyDown = (e: KeyboardEvent) => {\n const item = this.navigations[this.navigations.length - 1];\n if(!item) return;\n if(e.key === 'Escape' && (item.onEscape ? item.onEscape() : true)) {\n cancelEvent(e);\n this.back(item.type);\n }\n };\n\n private onTouchStart = (e: TouchEvent) => {\n if(e.touches.length > 1) return;\n this.debug && this.log('touchstart');\n\n if(isSwipingBackSafari(e)) {\n this.isPossibleSwipe = true;\n\n window.addEventListener('touchend', () => {\n setTimeout(() => {\n this.isPossibleSwipe = false;\n }, 100);\n }, {passive: true, once: true});\n }\n\n /* const detach = () => {\n window.removeEventListener('touchend', onTouchEnd);\n window.removeEventListener('touchmove', onTouchMove);\n };\n\n let moved = false;\n const onTouchMove = (e: TouchEvent) => {\n this.debug && this.log('touchmove');\n if(e.touches.length > 1) {\n detach();\n return;\n }\n\n moved = true;\n };\n\n const onTouchEnd = (e: TouchEvent) => {\n this.debug && this.log('touchend');\n if(e.touches.length > 1 || !moved) {\n detach();\n return;\n }\n\n isPossibleSwipe = true;\n doubleRaf().then(() => {\n isPossibleSwipe = false;\n });\n\n detach();\n };\n\n window.addEventListener('touchend', onTouchEnd, options);\n window.addEventListener('touchmove', onTouchMove, options); */\n };\n\n public overrideHash(hash: string = '') {\n if(hash && hash[0] !== '#') hash = '#' + hash;\n else if(hash === '#') hash = '';\n\n if(this.currentHash === hash) {\n return;\n }\n\n this.overriddenHash = this.currentHash = hash;\n this.replaceState();\n this.pushState();\n }\n\n private handleItem(item: NavigationItem) {\n const good = item.onPop(!this.manual ? false : undefined);\n this.debug && this.log('popstate, navigation:', item, this.navigations);\n if(good === false) {\n this.pushItem(item);\n } else if(!item.noBlurOnPop) {\n blurActiveElement(); // no better place for it\n }\n\n this.manual = false;\n }\n\n public findItemByType(type: NavigationItem['type']) {\n for(let i = this.navigations.length - 1; i >= 0; --i) {\n const item = this.navigations[i];\n if(item.type === type) {\n return {item, index: i};\n }\n }\n }\n\n public back(type?: NavigationItem['type']) {\n if(type) {\n const ret = this.findItemByType(type);\n if(ret) {\n this.backByItem(ret.item, ret.index);\n return;\n }\n }\n\n history.back();\n }\n\n public backByItem(item: NavigationItem, index = this.navigations.indexOf(item)) {\n this.manual = true;\n // ! commented because 'popstate' event will be fired with delay\n // if(index !== (this.navigations.length - 1)) {\n this.navigations.splice(index, 1);\n this.handleItem(item);\n // }\n }\n\n private onItemAdded(item: NavigationItem) {\n this.debug && this.log('onItemAdded', item, this.navigations);\n\n if(!item.noHistory) {\n this.pushState();\n }\n }\n\n public pushItem(item: NavigationItem) {\n this.navigations.push(item);\n this.onItemAdded(item);\n }\n\n public unshiftItem(item: NavigationItem) {\n this.navigations.unshift(item);\n this.onItemAdded(item);\n }\n\n public spliceItems(index: number, length: number, ...items: NavigationItem[]) {\n this.navigations.splice(index, length, ...items);\n items.forEach((item) => {\n this.onItemAdded(item);\n });\n }\n\n private pushState() {\n this.debug && this.log('push');\n this.manual = false;\n history.pushState(this.id, '');\n }\n\n public replaceState() {\n this.debug && this.log.warn('replace');\n\n const url = location.origin + location.pathname + location.search + this.overriddenHash;\n history.replaceState(this.id, '', url);\n }\n\n public removeItem(item: NavigationItem) {\n if(!item) {\n return;\n }\n\n indexOfAndSplice(this.navigations, item);\n }\n\n public removeByType(type: NavigationItem['type'], single = false) {\n for(let i = this.navigations.length - 1; i >= 0; --i) {\n const item = this.navigations[i];\n if(item.type === type) {\n this.navigations.splice(i, 1);\n\n if(single) {\n break;\n }\n }\n }\n }\n}\n\nconst appNavigationController = new AppNavigationController();\nMOUNT_CLASS_TO.appNavigationController = appNavigationController;\nexport default appNavigationController;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport appDialogsManager from '../lib/appManagers/appDialogsManager';\nimport Scrollable from './scrollable';\nimport InputSearch from './inputSearch';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport {i18n, LangPackKey} from '../lib/langPack';\nimport rootScope from '../lib/rootScope';\n\nexport class SearchGroup {\n container: HTMLDivElement;\n nameEl: HTMLDivElement;\n list: HTMLUListElement;\n\n constructor(\n public name: LangPackKey | boolean,\n public type: string,\n private clearable = true,\n className?: string,\n clickable = true,\n public autonomous = true,\n public onFound?: () => void,\n public noIcons?: boolean\n ) {\n this.list = appDialogsManager.createChatList();\n this.container = document.createElement('div');\n if(className) this.container.className = className;\n\n if(name) {\n this.nameEl = document.createElement('div');\n this.nameEl.classList.add('search-group__name');\n if(typeof(name) === 'string') {\n this.nameEl.append(i18n(name));\n }\n this.container.append(this.nameEl);\n }\n\n this.container.classList.add('search-group', 'search-group-' + type);\n this.container.append(this.list);\n this.container.style.display = 'none';\n\n if(clickable) {\n appDialogsManager.setListClickListener(this.list, onFound, undefined, autonomous);\n }\n }\n\n clear() {\n this.container.style.display = 'none';\n\n if(this.clearable) {\n this.list.replaceChildren();\n }\n }\n\n setActive() {\n this.container.style.display = '';\n }\n\n toggle() {\n if(this.list.childElementCount) {\n this.setActive();\n } else {\n this.clear();\n }\n }\n}\n\nexport type SearchGroupType = 'contacts' | 'globalContacts' | 'messages' | string;\n\nexport default class AppSearch {\n private minMsgId = 0;\n private loadedCount = -1;\n private foundCount = -1;\n\n private searchPromise: Promise<void> = null;\n private searchTimeout: number = 0;\n\n private query = '';\n\n private listsContainer: HTMLDivElement = null;\n\n private peerId: PeerId; // 0 - means global\n private threadId = 0;\n\n private scrollable: Scrollable;\n\n constructor(\n public container: HTMLElement,\n public searchInput: InputSearch,\n public searchGroups: {[group in SearchGroupType]: SearchGroup},\n public onSearch?: (count: number) => void,\n public noIcons?: boolean\n ) {\n this.scrollable = new Scrollable(this.container);\n this.listsContainer = this.scrollable.container as HTMLDivElement;\n for(const i in this.searchGroups) {\n this.listsContainer.append(this.searchGroups[i as SearchGroupType].container);\n }\n\n if(this.searchGroups.messages) {\n this.scrollable.setVirtualContainer(this.searchGroups.messages.list);\n }\n\n this.searchInput.onChange = (value) => {\n /* if(!value.trim()) {\n //this.peerId = 0;\n return;\n } */\n\n this.query = value;\n this.reset(false);\n this.searchMore();\n };\n\n this.scrollable.onScrolledBottom = () => {\n if(!this.query.trim()) return;\n\n if(!this.searchTimeout) {\n this.searchTimeout = window.setTimeout(() => {\n this.searchMore();\n this.searchTimeout = 0;\n }, 0);\n }\n };\n }\n\n public reset(all = true) {\n if(all) {\n this.searchInput.value = '';\n this.query = '';\n this.peerId = undefined;\n this.threadId = 0;\n }\n\n this.minMsgId = 0;\n this.loadedCount = -1;\n this.foundCount = -1;\n\n for(const i in this.searchGroups) {\n this.searchGroups[i as SearchGroupType].clear();\n }\n\n this.searchPromise = null;\n }\n\n public beginSearch(peerId?: PeerId, threadId = 0, query = '') {\n this.peerId = peerId;\n this.threadId = threadId;\n\n if(this.query !== query) {\n this.searchInput.inputField.value = query;\n }\n\n this.searchInput.input.focus();\n }\n\n public searchMore() {\n if(this.searchPromise) return this.searchPromise;\n\n const query = this.query;\n\n if(!query.trim()) {\n this.onSearch && this.onSearch(0);\n return;\n }\n\n if(this.foundCount !== -1 && this.loadedCount >= this.foundCount) {\n return Promise.resolve();\n }\n\n const maxId = this.minMsgId || 0;\n\n return this.searchPromise = rootScope.managers.appMessagesManager.getSearch({\n peerId: this.peerId,\n query,\n inputFilter: {_: 'inputMessagesFilterEmpty'},\n maxId,\n limit: 20,\n threadId: this.threadId\n }).then((res) => {\n this.searchPromise = null;\n\n if(this.searchInput.value !== query) {\n return;\n }\n\n // console.log('input search result:', this.peerId, query, null, maxId, 20, res);\n\n const {count, history} = res;\n\n if(history.length && history[0].mid === this.minMsgId) {\n history.shift();\n }\n\n const searchGroup = this.searchGroups.messages;\n\n history.forEach((message) => {\n try {\n const peerId = this.peerId ? message.fromId : message.peerId;\n appDialogsManager.addDialogAndSetLastMessage({\n peerId,\n container: this.scrollable/* searchGroup.list */,\n avatarSize: 'bigger',\n meAsSaved: false,\n message,\n query,\n noIcons: this.noIcons\n });\n } catch(err) {\n console.error('[appSearch] render search result', err);\n }\n });\n\n searchGroup.toggle();\n\n this.minMsgId = history.length && history[history.length - 1].mid;\n\n if(this.loadedCount === -1) {\n this.loadedCount = 0;\n }\n this.loadedCount += history.length;\n\n if(this.foundCount === -1) {\n this.foundCount = count;\n\n if(searchGroup.nameEl) {\n replaceContent(searchGroup.nameEl, i18n(count ? 'Chat.Search.MessagesFound' : 'Chat.Search.NoMessagesFound', [count]));\n }\n\n this.onSearch && this.onSearch(this.foundCount);\n }\n }).catch((err) => {\n console.error('search error', err);\n this.searchPromise = null;\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyInputMessagesFilter, MyMessage} from '../lib/appManagers/appMessagesManager';\nimport appDialogsManager, {DIALOG_LIST_ELEMENT_TAG} from '../lib/appManagers/appDialogsManager';\nimport {logger} from '../lib/logger';\nimport rootScope from '../lib/rootScope';\nimport {SearchGroup, SearchGroupType} from './appSearch';\nimport {horizontalMenu} from './horizontalMenu';\nimport LazyLoadQueue from './lazyLoadQueue';\nimport {putPreloader} from './putPreloader';\nimport ripple from './ripple';\nimport Scrollable, {ScrollableX} from './scrollable';\nimport useHeavyAnimationCheck, {getHeavyAnimationPromise} from '../hooks/useHeavyAnimationCheck';\nimport I18n, {LangPackKey, i18n} from '../lib/langPack';\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport {getMiddleware, Middleware} from '../helpers/middleware';\nimport {ChannelParticipant, Chat, ChatFull, ChatParticipant, ChatParticipants, Document, Message, MessageMedia, Photo, User, WebPage} from '../layer';\nimport SortedUserList from './sortedUserList';\nimport findUpTag from '../helpers/dom/findUpTag';\nimport appSidebarRight from './sidebarRight';\nimport mediaSizes from '../helpers/mediaSizes';\nimport appImManager from '../lib/appManagers/appImManager';\nimport positionElementByIndex from '../helpers/dom/positionElementByIndex';\nimport cleanSearchText from '../helpers/cleanSearchText';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport handleTabSwipe from '../helpers/dom/handleTabSwipe';\nimport windowSize from '../helpers/windowSize';\nimport {formatPhoneNumber} from '../helpers/formatPhoneNumber';\nimport {ButtonMenuItemOptions, ButtonMenuSync} from './buttonMenu';\nimport PopupForward from './popups/forward';\nimport PopupDeleteMessages from './popups/deleteMessages';\nimport Row from './row';\nimport htmlToDocumentFragment from '../helpers/dom/htmlToDocumentFragment';\nimport {SearchSelection} from './chat/selection';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {attachClickEvent, simulateClickEvent} from '../helpers/dom/clickEvent';\nimport {MyDocument} from '../lib/appManagers/appDocsManager';\nimport AppMediaViewer from './appMediaViewer';\nimport lockTouchScroll from '../helpers/dom/lockTouchScroll';\nimport copy from '../helpers/object/copy';\nimport getObjectKeysAndSort from '../helpers/object/getObjectKeysAndSort';\nimport safeAssign from '../helpers/object/safeAssign';\nimport escapeRegExp from '../helpers/string/escapeRegExp';\nimport findAndSplice from '../helpers/array/findAndSplice';\nimport {ScrollStartCallbackDimensions} from '../helpers/fastSmoothScroll';\nimport setInnerHTML from '../helpers/dom/setInnerHTML';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport choosePhotoSize from '../lib/appManagers/utils/photos/choosePhotoSize';\nimport wrapWebPageDescription from './wrappers/webPageDescription';\nimport wrapWebPageTitle from './wrappers/webPageTitle';\nimport wrapAbbreviation from '../lib/richTextProcessor/wrapAbbreviation';\nimport matchUrl from '../lib/richTextProcessor/matchUrl';\nimport wrapPlainText from '../lib/richTextProcessor/wrapPlainText';\nimport wrapRichText from '../lib/richTextProcessor/wrapRichText';\nimport wrapSenderToPeer from './wrappers/senderToPeer';\nimport wrapSentTime from './wrappers/sentTime';\nimport getMediaFromMessage from '../lib/appManagers/utils/messages/getMediaFromMessage';\nimport filterMessagesByInputFilter from '../lib/appManagers/utils/messages/filterMessagesByInputFilter';\nimport getChatMembersString from './wrappers/getChatMembersString';\nimport getUserStatusString from './wrappers/getUserStatusString';\nimport getParticipantPeerId from '../lib/appManagers/utils/chats/getParticipantPeerId';\nimport {Awaited} from '../types';\nimport {attachContextMenuListener} from '../helpers/dom/attachContextMenuListener';\nimport contextMenuController from '../helpers/contextMenuController';\nimport positionMenu from '../helpers/positionMenu';\nimport apiManagerProxy from '../lib/mtproto/mtprotoworker';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport SwipeHandler from './swipeHandler';\nimport wrapDocument from './wrappers/document';\nimport wrapPhoto from './wrappers/photo';\nimport wrapVideo from './wrappers/video';\nimport noop from '../helpers/noop';\nimport wrapMediaSpoiler, {onMediaSpoilerClick} from './wrappers/mediaSpoiler';\nimport filterAsync from '../helpers/array/filterAsync';\nimport ChatContextMenu from './chat/contextMenu';\nimport PopupElement from './popups';\nimport getParticipantRank from '../lib/appManagers/utils/chats/getParticipantRank';\n\n// const testScroll = false;\n\nexport type SearchSuperType = MyInputMessagesFilter/* | 'members' */;\nexport type SearchSuperContext = {\n peerId: PeerId,\n inputFilter: {_: MyInputMessagesFilter},\n query?: string,\n maxId?: number,\n folderId?: number,\n threadId?: number,\n date?: number,\n nextRate?: number,\n minDate?: number,\n maxDate?: number\n};\n\nexport type SearchSuperMediaType = 'members' | 'media' | 'files' | 'links' | 'music' | 'chats' | 'voice' | 'groups';\nexport type SearchSuperMediaTab = {\n inputFilter: SearchSuperType,\n name: LangPackKey,\n type: SearchSuperMediaType,\n contentTab?: HTMLElement,\n menuTab?: HTMLElement,\n scroll?: {scrollTop: number, scrollHeight: number}\n};\n\nclass SearchContextMenu {\n private buttons: (ButtonMenuItemOptions & {verify?: () => boolean | Promise<boolean>, withSelection?: true})[];\n private element: HTMLElement;\n private target: HTMLElement;\n private peerId: PeerId;\n private mid: number;\n private isSelected: boolean;\n private managers: AppManagers;\n private noForwards: boolean;\n private message: MyMessage;\n private selectedMessages: MyMessage[];\n\n constructor(\n private attachTo: HTMLElement,\n private searchSuper: AppSearchSuper,\n private listenerSetter: ListenerSetter\n ) {\n this.managers = searchSuper.managers;\n\n const onContextMenu: Parameters<typeof attachContextMenuListener>[0]['callback'] = (e) => {\n if(this.init) {\n this.init();\n this.init = null;\n }\n\n let item: HTMLElement;\n try {\n item = findUpClassName(e.target, 'search-super-item');\n } catch(e) {}\n\n if(!item) return;\n\n if(e instanceof MouseEvent) e.preventDefault();\n if(this.element.classList.contains('active')) {\n return false;\n }\n if(e instanceof MouseEvent) e.cancelBubble = true;\n\n const r = async() => {\n this.target = item;\n this.peerId = item.dataset.peerId.toPeerId();\n this.mid = +item.dataset.mid;\n this.isSelected = searchSuper.selection.isMidSelected(this.peerId, this.mid);\n this.message = await this.managers.appMessagesManager.getMessageByPeer(this.peerId, this.mid);\n this.noForwards = searchSuper.selection.isSelecting ?\n this.searchSuper.selection.selectionForwardBtn.classList.contains('hide') :\n !(await this.managers.appMessagesManager.canForward(this.message));\n this.selectedMessages = searchSuper.selection.isSelecting ? await searchSuper.selection.getSelectedMessages() : undefined;\n\n await Promise.all(this.buttons.map(async(button) => {\n let good: boolean;\n\n if(this.searchSuper.selection.isSelecting && !button.withSelection) {\n good = false;\n } else {\n good = button.verify ? !!(await button.verify()) : true;\n }\n\n button.element.classList.toggle('hide', !good);\n }));\n\n item.classList.add('menu-open');\n\n positionMenu(e, this.element);\n contextMenuController.openBtnMenu(this.element, () => {\n item.classList.remove('menu-open');\n });\n };\n\n r();\n };\n\n if(IS_TOUCH_SUPPORTED) {\n\n } else {\n attachContextMenuListener({\n element: attachTo,\n callback: onContextMenu as any,\n listenerSetter\n });\n }\n }\n\n private init() {\n this.buttons = [{\n icon: 'forward',\n text: 'Forward',\n onClick: this.onForwardClick,\n verify: () => !this.noForwards\n }, {\n icon: 'forward',\n text: 'Message.Context.Selection.Forward',\n onClick: this.onForwardClick,\n verify: () => this.searchSuper.selection.isSelecting && !this.noForwards,\n withSelection: true\n }, {\n icon: 'download',\n text: 'MediaViewer.Context.Download',\n onClick: () => ChatContextMenu.onDownloadClick(this.message, this.noForwards),\n verify: () => !this.searchSuper.selection.isSelecting && ChatContextMenu.canDownload(this.message, undefined, this.noForwards)\n }, {\n icon: 'download',\n text: 'Message.Context.Selection.Download',\n onClick: () => ChatContextMenu.onDownloadClick(this.selectedMessages, this.noForwards),\n verify: () => this.searchSuper.selection.isSelecting && ChatContextMenu.canDownload(this.selectedMessages, undefined, this.noForwards),\n withSelection: true\n }, {\n icon: 'message',\n text: 'Message.Context.Goto',\n onClick: this.onGotoClick,\n withSelection: true\n }, {\n icon: 'select',\n text: 'Message.Context.Select',\n onClick: this.onSelectClick,\n verify: () => !this.isSelected,\n withSelection: true\n }, {\n icon: 'select',\n text: 'Message.Context.Selection.Clear',\n onClick: this.onClearSelectionClick,\n verify: () => this.isSelected,\n withSelection: true\n }, {\n icon: 'delete danger',\n text: 'Delete',\n onClick: this.onDeleteClick,\n verify: () => !this.searchSuper.selection.isSelecting && this.managers.appMessagesManager.canDeleteMessage(this.message)\n }, {\n icon: 'delete danger',\n text: 'Message.Context.Selection.Delete',\n onClick: this.onDeleteClick,\n verify: () => this.searchSuper.selection.isSelecting && !this.searchSuper.selection.selectionDeleteBtn.classList.contains('hide'),\n withSelection: true\n }];\n\n this.element = ButtonMenuSync({buttons: this.buttons, listenerSetter: this.listenerSetter});\n this.element.classList.add('search-contextmenu', 'contextmenu');\n document.getElementById('page-chats').append(this.element);\n }\n\n private onGotoClick = () => {\n appImManager.setInnerPeer({\n peerId: this.peerId,\n lastMsgId: this.mid,\n threadId: this.searchSuper.searchContext.threadId\n });\n };\n\n private onForwardClick = () => {\n if(this.searchSuper.selection.isSelecting) {\n simulateClickEvent(this.searchSuper.selection.selectionForwardBtn);\n } else {\n PopupElement.createPopup(PopupForward, {\n [this.peerId]: [this.mid]\n });\n }\n };\n\n private onSelectClick = () => {\n this.searchSuper.selection.toggleByElement(this.target);\n };\n\n private onClearSelectionClick = () => {\n this.searchSuper.selection.cancelSelection();\n };\n\n private onDeleteClick = () => {\n if(this.searchSuper.selection.isSelecting) {\n simulateClickEvent(this.searchSuper.selection.selectionDeleteBtn);\n } else {\n PopupElement.createPopup(PopupDeleteMessages, this.peerId, [this.mid], 'chat');\n }\n };\n}\n\nexport type ProcessSearchSuperResult = {\n message: Message.message,\n middleware: Middleware,\n promises: Promise<any>[],\n elemsToAppend: {element: HTMLElement, message: any}[],\n inputFilter: MyInputMessagesFilter,\n searchGroup?: SearchGroup\n};\n\nexport default class AppSearchSuper {\n public tabs: {[t in SearchSuperType]: HTMLDivElement} = {} as any;\n\n public mediaTab: SearchSuperMediaTab;\n\n public container: HTMLElement;\n public nav: HTMLElement;\n public navScrollableContainer: HTMLDivElement;\n public tabsContainer: HTMLElement;\n public navScrollable: ScrollableX;\n private tabsMenu: HTMLElement;\n private prevTabId = -1;\n\n private lazyLoadQueue = new LazyLoadQueue();\n public middleware = getMiddleware();\n\n public historyStorage: Partial<{[type in SearchSuperType]: {mid: number, peerId: PeerId}[]}> = {};\n public usedFromHistory: Partial<{[type in SearchSuperType]: number}> = {};\n\n public searchContext: SearchSuperContext;\n public loadMutex: Promise<any> = Promise.resolve();\n\n private nextRates: Partial<{[type in SearchSuperType]: number}> = {};\n private loadPromises: Partial<{[type in SearchSuperType]: Promise<void>}> = {};\n private loaded: Partial<{[type in SearchSuperType]: boolean}> = {};\n private loadedChats = false;\n private firstLoad = true;\n\n private log = logger('SEARCH-SUPER');\n public selectTab: ReturnType<typeof horizontalMenu>;\n\n private monthContainers: Partial<{\n [type in SearchSuperType]: {\n [timestamp: number]: {\n container: HTMLElement,\n items: HTMLElement\n }\n }\n }> = {};\n\n private searchGroupMedia: SearchGroup;\n\n public mediaTabsMap: Map<SearchSuperMediaType, SearchSuperMediaTab> = new Map();\n\n private membersList: SortedUserList;\n\n private skipScroll: boolean;\n\n // * arguments\n public mediaTabs: SearchSuperMediaTab[];\n public scrollable: Scrollable;\n public searchGroups?: {[group in SearchGroupType]: SearchGroup};\n public asChatList? = false;\n public groupByMonth? = true;\n public hideEmptyTabs? = true;\n public onChangeTab?: (mediaTab: SearchSuperMediaTab) => void;\n public showSender? = false;\n\n private searchContextMenu: SearchContextMenu;\n public selection: SearchSelection;\n\n public scrollStartCallback: (dimensions: ScrollStartCallbackDimensions) => void;\n\n public managers: AppManagers;\n private loadFirstTimePromise: Promise<void>;\n\n private listenerSetter: ListenerSetter;\n private swipeHandler: SwipeHandler;\n\n constructor(options: Pick<AppSearchSuper, 'mediaTabs' | 'scrollable' | 'searchGroups' | 'asChatList' | 'groupByMonth' | 'hideEmptyTabs' | 'onChangeTab' | 'showSender' | 'managers'>) {\n safeAssign(this, options);\n\n this.container = document.createElement('div');\n this.container.classList.add('search-super');\n\n this.listenerSetter = new ListenerSetter();\n this.searchContextMenu = new SearchContextMenu(this.container, this, this.listenerSetter);\n this.selection = new SearchSelection(this, this.managers, this.listenerSetter);\n\n const navScrollableContainer = this.navScrollableContainer = document.createElement('div');\n navScrollableContainer.classList.add('search-super-tabs-scrollable', 'menu-horizontal-scrollable', 'sticky');\n\n const navScrollable = this.navScrollable = new ScrollableX(navScrollableContainer);\n navScrollable.container.classList.add('search-super-nav-scrollable');\n\n const nav = this.nav = document.createElement('nav');\n nav.classList.add('search-super-tabs', 'menu-horizontal-div');\n this.tabsMenu = nav;\n\n navScrollable.container.append(nav);\n\n for(const mediaTab of this.mediaTabs) {\n const menuTab = document.createElement('div');\n menuTab.classList.add('menu-horizontal-div-item');\n const span = document.createElement('span');\n const i = document.createElement('i');\n\n span.append(i18n(mediaTab.name));\n span.append(i);\n\n menuTab.append(span);\n\n ripple(menuTab);\n\n this.tabsMenu.append(menuTab);\n\n this.mediaTabsMap.set(mediaTab.type, mediaTab);\n\n mediaTab.menuTab = menuTab;\n }\n\n this.tabsContainer = document.createElement('div');\n this.tabsContainer.classList.add('search-super-tabs-container', 'tabs-container');\n\n let unlockScroll: ReturnType<typeof lockTouchScroll>;\n if(IS_TOUCH_SUPPORTED) {\n this.swipeHandler = handleTabSwipe({\n element: this.tabsContainer,\n onSwipe: (xDiff, yDiff, e) => {\n xDiff *= -1;\n yDiff *= -1;\n const prevId = this.selectTab.prevId();\n const children = Array.from(this.tabsMenu.children) as HTMLElement[];\n let idx: number;\n if(xDiff > 0) {\n for(let i = prevId + 1; i < children.length; ++i) {\n if(!children[i].classList.contains('hide')) {\n idx = i;\n break;\n }\n }\n } else {\n for(let i = prevId - 1; i >= 0; --i) {\n if(!children[i].classList.contains('hide')) {\n idx = i;\n break;\n }\n }\n }\n\n if(idx !== undefined) {\n unlockScroll = lockTouchScroll(this.tabsContainer);\n this.selectTab(idx);\n }\n },\n verifyTouchTarget: (e) => {\n return !findUpClassName(e.target, 'scrollable-x');\n }\n });\n }\n\n for(const mediaTab of this.mediaTabs) {\n const container = document.createElement('div');\n container.classList.add('search-super-container-' + mediaTab.type, 'tabs-tab');\n\n const content = document.createElement('div');\n content.classList.add('search-super-content-' + mediaTab.type);\n\n container.append(content);\n\n this.tabsContainer.append(container);\n\n this.tabs[mediaTab.inputFilter] = content;\n\n mediaTab.contentTab = content;\n }\n\n this.container.append(navScrollableContainer, this.tabsContainer);\n\n // * construct end\n\n this.searchGroupMedia = new SearchGroup(false, 'messages', true);\n\n this.scrollable.onScrolledBottom = () => {\n if(this.mediaTab.contentTab && this.canLoadMediaTab(this.mediaTab)/* && false */) {\n // this.log('onScrolledBottom will load media');\n this.load(true);\n }\n };\n // this.scroll.attachSentinels(undefined, 400);\n\n this.selectTab = horizontalMenu(this.tabsMenu, this.tabsContainer, (id, tabContent, animate) => {\n if(this.prevTabId === id && !this.skipScroll) {\n this.scrollable.scrollIntoViewNew({\n element: this.container,\n position: 'start',\n startCallback: this.scrollStartCallback\n });\n return;\n }\n\n const newMediaTab = this.mediaTabs[id];\n if(this.onChangeTab) {\n this.onChangeTab(newMediaTab);\n }\n\n const fromMediaTab = this.mediaTab;\n this.mediaTab = newMediaTab;\n\n if(this.prevTabId !== -1 && animate) {\n this.onTransitionStart();\n }\n\n if(this.skipScroll) {\n this.skipScroll = false;\n } else {\n const offsetTop = this.container.offsetTop;\n let scrollTop = this.scrollable.scrollTop;\n if(scrollTop < offsetTop) {\n this.scrollable.scrollIntoViewNew({\n element: this.container,\n position: 'start',\n startCallback: this.scrollStartCallback\n });\n scrollTop = offsetTop;\n }\n\n fromMediaTab.scroll = {scrollTop: scrollTop, scrollHeight: this.scrollable.scrollHeight};\n\n if(newMediaTab.scroll === undefined) {\n const rect = this.container.getBoundingClientRect();\n const rect2 = this.container.parentElement.getBoundingClientRect();\n const diff = rect.y - rect2.y;\n\n if(scrollTop > diff) {\n newMediaTab.scroll = {scrollTop: diff, scrollHeight: 0};\n }\n }\n\n if(newMediaTab.scroll) {\n const diff = fromMediaTab.scroll.scrollTop - newMediaTab.scroll.scrollTop;\n // console.log('what you gonna do', this.goingHard, diff);\n\n // this.scrollable.scrollTop = scrollTop;\n if(diff/* && diff < 0 */) {\n /* if(diff > -(fromMediaTab.contentTab.scrollHeight + this.nav.scrollHeight)) {\n fromMediaTab.contentTab.style.transform = `translateY(${diff}px)`;\n this.scrollable.scrollTop = scrollTop - diff;\n } else { */\n newMediaTab.contentTab.style.transform = `translateY(${diff}px)`;\n // }\n }\n }\n }\n\n /* if(this.prevTabId !== -1 && nav.offsetTop) {\n this.scrollable.scrollTop -= nav.offsetTop;\n } */\n\n /* this.log('setVirtualContainer', id, this.sharedMediaSelected, this.sharedMediaSelected.childElementCount);\n this.scroll.setVirtualContainer(this.sharedMediaSelected); */\n\n if(this.prevTabId !== -1 && !newMediaTab.contentTab.childElementCount) { // quick brown fix\n // this.contentContainer.classList.remove('loaded');\n this.load(true);\n }\n\n this.prevTabId = id;\n }, () => {\n this.scrollable.onScroll();\n\n // console.log('what y', this.tabSelected.style.transform);\n if(this.mediaTab.scroll !== undefined) {\n this.mediaTab.contentTab.style.transform = '';\n this.scrollable.scrollTop = this.mediaTab.scroll.scrollTop;\n }\n\n if(unlockScroll) {\n unlockScroll();\n unlockScroll = undefined;\n }\n\n this.onTransitionEnd();\n }, undefined, navScrollable, this.listenerSetter);\n\n attachClickEvent(this.tabsContainer, (e) => {\n if(this.selection.isSelecting) {\n cancelEvent(e);\n this.selection.toggleByElement(findUpClassName(e.target, 'search-super-item'));\n }\n }, {capture: true, passive: false, listenerSetter: this.listenerSetter});\n\n const onMediaClick = async(className: string, targetClassName: string, inputFilter: MyInputMessagesFilter, e: MouseEvent) => {\n const target = findUpClassName(e.target as HTMLDivElement, className);\n if(!target) return;\n\n const mid = +target.dataset.mid;\n if(!mid) {\n this.log.warn('no messageId by click on target:', target);\n return;\n }\n\n const mediaSpoiler: HTMLElement = target.querySelector('.media-spoiler-container');\n if(mediaSpoiler) {\n onMediaSpoilerClick({\n event: e,\n mediaSpoiler\n })\n return;\n }\n\n const peerId = target.dataset.peerId.toPeerId();\n\n const targets = (Array.from(this.tabs[inputFilter].querySelectorAll('.' + targetClassName)) as HTMLElement[]).map((el) => {\n const containerEl = findUpClassName(el, className);\n return {\n element: el,\n mid: +containerEl.dataset.mid,\n peerId: containerEl.dataset.peerId.toPeerId()\n };\n });\n\n // const ids = Object.keys(this.mediaDivsByIds).map((k) => +k).sort((a, b) => a - b);\n const idx = targets.findIndex((item) => item.mid === mid && item.peerId === peerId);\n\n const message = await this.managers.appMessagesManager.getMessageByPeer(peerId, mid);\n new AppMediaViewer()\n .setSearchContext(this.copySearchContext(inputFilter))\n .openMedia({\n message,\n target: targets[idx].element,\n fromRight: 0,\n reverse: false,\n prevTargets: targets.slice(0, idx),\n nextTargets: targets.slice(idx + 1)\n });\n };\n\n attachClickEvent(this.tabs.inputMessagesFilterPhotoVideo, onMediaClick.bind(null, 'grid-item', 'grid-item', 'inputMessagesFilterPhotoVideo'), {listenerSetter: this.listenerSetter});\n attachClickEvent(this.tabs.inputMessagesFilterDocument, onMediaClick.bind(null, 'document-with-thumb', 'media-container', 'inputMessagesFilterDocument'), {listenerSetter: this.listenerSetter});\n\n /* attachClickEvent(this.tabs.inputMessagesFilterUrl, (e) => {\n const target = e.target as HTMLElement;\n if(target.tagName === 'A') {\n return;\n }\n\n try {\n const a = findUpClassName(target, 'row').querySelector('.anchor-url:last-child') as HTMLAnchorElement;\n a.click();\n } catch(err) {}\n }); */\n\n this.mediaTab = this.mediaTabs[0];\n\n useHeavyAnimationCheck(() => {\n this.lazyLoadQueue.lock();\n }, () => {\n this.lazyLoadQueue.unlockAndRefresh(); // ! maybe not so efficient\n }, this.listenerSetter);\n }\n\n private onTransitionStart = () => {\n this.container.classList.add('sliding');\n };\n\n private onTransitionEnd = () => {\n this.container.classList.remove('sliding');\n };\n\n public filterMessagesByType(messages: any[], type: SearchSuperType): MyMessage[] {\n return filterMessagesByInputFilter(type, messages, messages.length);\n }\n\n private processEmptyFilter({message, searchGroup}: ProcessSearchSuperResult) {\n const loadPromises: Promise<any>[] = [];\n const dialogElement = appDialogsManager.addDialogNew({\n peerId: message.peerId,\n container: searchGroup.list,\n avatarSize: 'bigger',\n loadPromises\n });\n\n const setLastMessagePromise = appDialogsManager.setLastMessageN({\n dialog: {\n _: 'dialog',\n peerId: message.peerId\n } as any,\n lastMessage: message,\n dialogElement,\n highlightWord: this.searchContext.query\n });\n\n loadPromises.push(setLastMessagePromise);\n return Promise.all(loadPromises).then(noop);\n }\n\n private async processPhotoVideoFilter({message, promises, middleware}: ProcessSearchSuperResult) {\n const media = getMediaFromMessage(message, true);\n\n const div = document.createElement('div');\n div.classList.add('grid-item');\n // this.log(message, photo);\n\n let wrapped: Awaited<ReturnType<typeof wrapPhoto>>;\n const size = choosePhotoSize(media, 200, 200);\n if(media._ !== 'photo') {\n wrapped = await (await wrapVideo({\n doc: media,\n message,\n container: div,\n boxWidth: 0,\n boxHeight: 0,\n lazyLoadQueue: this.lazyLoadQueue,\n middleware,\n onlyPreview: true,\n withoutPreloader: true,\n noPlayButton: true,\n photoSize: size\n })).thumb;\n } else {\n wrapped = await wrapPhoto({\n photo: media,\n message,\n container: div,\n boxWidth: 0,\n boxHeight: 0,\n lazyLoadQueue: this.lazyLoadQueue,\n middleware,\n withoutPreloader: true,\n noBlur: true,\n size\n });\n }\n\n if((message.media as MessageMedia.messageMediaPhoto).pFlags.spoiler) {\n const mediaSpoiler = await wrapMediaSpoiler({\n animationGroup: 'chat',\n media,\n middleware,\n width: 140,\n height: 140,\n multiply: 0.3\n });\n\n div.append(mediaSpoiler);\n }\n\n [\n wrapped.images.thumb,\n wrapped.images.full\n ].filter(Boolean).forEach((image) => {\n image.classList.add('grid-item-media');\n });\n\n promises.push(wrapped.loadPromises.thumb);\n\n return {element: div, message};\n }\n\n private async processDocumentFilter({message, inputFilter}: ProcessSearchSuperResult) {\n const document = getMediaFromMessage(message, true) as Document.document;\n const showSender = this.showSender || (['voice', 'round'] as MyDocument['type'][]).includes(document.type);\n\n const div = await wrapDocument({\n message,\n withTime: !showSender,\n fontWeight: 400,\n voiceAsMusic: true,\n showSender,\n searchContext: this.copySearchContext(inputFilter),\n lazyLoadQueue: this.lazyLoadQueue,\n autoDownloadSize: 0,\n getSize: () => 320\n });\n\n if((['audio', 'voice', 'round'] as MyDocument['type'][]).includes(document.type)) {\n div.classList.add('audio-48');\n }\n\n return {message, element: div};\n }\n\n private async processUrlFilter({message, promises, middleware}: ProcessSearchSuperResult) {\n let webPage = (message.media as MessageMedia.messageMediaWebPage)?.webpage as WebPage.webPage | WebPage.webPageEmpty;\n\n if(!webPage) {\n const entity = message.totalEntities ? message.totalEntities.find((e: any) => e._ === 'messageEntityUrl' || e._ === 'messageEntityTextUrl') : null;\n let url: string, display_url: string, sliced: string;\n\n if(!entity) {\n const match = matchUrl(message.message);\n if(!match) {\n return;\n }\n\n url = match[0];\n } else {\n sliced = message.message.slice(entity.offset, entity.offset + entity.length);\n }\n\n if(entity?._ === 'messageEntityTextUrl') {\n url = entity.url;\n // display_url = sliced;\n } else {\n url = url || sliced;\n }\n\n display_url = url;\n\n const same = message.message === url;\n if(!url.match(/^(ftp|http|https):\\/\\//)) {\n display_url = 'https://' + url;\n url = url.includes('@') ? url : 'https://' + url;\n }\n\n display_url = new URL(display_url).hostname;\n\n webPage = {\n _: 'webPage',\n url,\n display_url,\n id: '',\n hash: 0\n };\n\n if(!same) {\n webPage.description = message.message;\n }\n }\n\n if(webPage._ === 'webPageEmpty') {\n return;\n }\n\n const previewDiv = document.createElement('div');\n previewDiv.classList.add('preview');\n\n // this.log('wrapping webpage', webpage);\n\n if(webPage.photo) {\n const res = wrapPhoto({\n container: previewDiv,\n message: null,\n photo: webPage.photo as Photo.photo,\n boxWidth: 0,\n boxHeight: 0,\n withoutPreloader: true,\n lazyLoadQueue: this.lazyLoadQueue,\n middleware,\n size: choosePhotoSize(webPage.photo as Photo.photo, 60, 60, false),\n loadPromises: promises,\n noBlur: true\n });\n } else {\n previewDiv.classList.add('empty');\n setInnerHTML(previewDiv, wrapAbbreviation(webPage.title || webPage.display_url || webPage.description || webPage.url, true));\n }\n\n const title = wrapWebPageTitle(webPage);\n\n const subtitleFragment = wrapWebPageDescription(webPage);\n const aFragment = htmlToDocumentFragment(wrapRichText(webPage.url || ''));\n const a = aFragment.firstElementChild;\n if(a instanceof HTMLAnchorElement) {\n try { // can have 'URIError: URI malformed'\n a.innerText = decodeURIComponent(a.href);\n } catch(err) {\n\n }\n }\n\n if(subtitleFragment.firstChild) {\n subtitleFragment.append('\\n');\n }\n\n subtitleFragment.append(a);\n\n if(this.showSender) {\n subtitleFragment.append('\\n', await wrapSenderToPeer(message));\n }\n\n if(!title.textContent) {\n // title = new URL(webpage.url).hostname;\n title.append(wrapPlainText(webPage.display_url.split('/', 1)[0]));\n }\n\n const row = new Row({\n title,\n titleRight: wrapSentTime(message),\n subtitle: subtitleFragment,\n havePadding: true,\n clickable: true,\n noRipple: true\n });\n\n row.applyMediaElement(previewDiv, 'big');\n\n if(row.container.innerText.trim().length) {\n return {message, element: row.container};\n }\n }\n\n public async performSearchResult(messages: any[], mediaTab: SearchSuperMediaTab, append = true) {\n const elemsToAppend: {element: HTMLElement, message: any}[] = [];\n const sharedMediaDiv: HTMLElement = mediaTab.contentTab;\n const promises: Promise<any>[] = [];\n const middleware = this.middleware.get();\n let inputFilter = mediaTab.inputFilter;\n\n await getHeavyAnimationPromise();\n\n let searchGroup: SearchGroup;\n if(inputFilter === 'inputMessagesFilterPhotoVideo' && !!this.searchContext.query.trim()) {\n inputFilter = 'inputMessagesFilterEmpty';\n searchGroup = this.searchGroupMedia;\n sharedMediaDiv.append(searchGroup.container);\n } else if(inputFilter === 'inputMessagesFilterEmpty') {\n searchGroup = this.searchGroups.messages;\n }\n\n const options: ProcessSearchSuperResult = {\n elemsToAppend,\n inputFilter,\n message: undefined,\n middleware,\n promises,\n searchGroup\n };\n\n let processCallback: (options: ProcessSearchSuperResult) => any;\n\n // https://core.telegram.org/type/MessagesFilter\n switch(inputFilter) {\n case 'inputMessagesFilterEmpty': {\n processCallback = this.processEmptyFilter;\n break;\n }\n\n case 'inputMessagesFilterPhotoVideo': {\n processCallback = this.processPhotoVideoFilter;\n break;\n }\n\n case 'inputMessagesFilterVoice':\n case 'inputMessagesFilterRoundVoice':\n case 'inputMessagesFilterMusic':\n case 'inputMessagesFilterDocument': {\n processCallback = this.processDocumentFilter;\n break;\n }\n\n case 'inputMessagesFilterUrl': {\n processCallback = this.processUrlFilter;\n break;\n }\n\n default:\n // this.log.warn('death is my friend', messages);\n break;\n }\n\n if(processCallback) {\n processCallback = processCallback.bind(this);\n\n type K = {element: HTMLElement, message: Message.message | Message.messageService};\n const results: (Promise<K> | K)[] = messages.map(async(message) => {\n try {\n options.message = message;\n return await processCallback(options);\n } catch(err) {\n this.log.error('error rendering filter', inputFilter, options, message, err);\n }\n });\n\n const awaited = (await Promise.all(results)).filter(Boolean);\n elemsToAppend.push(...awaited);\n }\n\n if(searchGroup && searchGroup.list.childElementCount) {\n searchGroup.setActive();\n }\n\n if(this.loadMutex) {\n promises.push(this.loadMutex);\n }\n\n if(promises.length) {\n await Promise.all(promises);\n if(!middleware()) {\n // this.log.warn('peer changed');\n return;\n }\n }\n\n if(elemsToAppend.length) {\n const method = append ? 'append' : 'prepend';\n elemsToAppend.forEach((details) => {\n const {element, message} = details;\n if(!message) {\n debugger;\n }\n\n const monthContainer = this.getMonthContainerByTimestamp(this.groupByMonth ? message.date : 0, inputFilter);\n element.classList.add('search-super-item');\n element.dataset.mid = '' + message.mid;\n element.dataset.peerId = '' + message.peerId;\n monthContainer.items[method](element);\n\n if(this.selection?.isSelecting) {\n this.selection.toggleElementCheckbox(element, true);\n }\n });\n }\n\n // if(type !== 'inputMessagesFilterEmpty') {\n this.afterPerforming(inputFilter === 'inputMessagesFilterEmpty' ? 1 : elemsToAppend.length, sharedMediaDiv);\n // }\n }\n\n private afterPerforming(length: number, contentTab: HTMLElement) {\n if(contentTab) {\n const parent = contentTab.parentElement;\n Array.from(parent.children).slice(1).forEach((child) => {\n child.remove();\n });\n\n // this.contentContainer.classList.add('loaded');\n\n if(!length && !contentTab.childElementCount) {\n const div = document.createElement('div');\n div.innerText = 'Nothing interesting here yet...';\n div.classList.add('position-center', 'text-center', 'content-empty', 'no-select');\n\n parent.append(div);\n }\n }\n }\n\n private loadChats() {\n const renderedPeerIds: Set<PeerId> = new Set();\n const middleware = this.middleware.get();\n\n for(const i in this.searchGroups) {\n const group = this.searchGroups[i as SearchGroupType];\n this.tabs.inputMessagesFilterEmpty.append(group.container);\n group.clear();\n }\n\n const query = this.searchContext.query;\n if(query) {\n const setResults = (results: PeerId[], group: SearchGroup, showMembersCount = false) => {\n results.map((peerId) => {\n if(renderedPeerIds.has(peerId)) {\n return;\n }\n\n renderedPeerIds.add(peerId);\n\n const {dom} = appDialogsManager.addDialogNew({\n peerId: peerId,\n container: group.list,\n avatarSize: 'abitbigger',\n autonomous: group.autonomous\n });\n\n return {dom, peerId};\n }).filter(Boolean).forEach(async({dom, peerId}) => {\n const peer = await this.managers.appPeersManager.getPeer(peerId);\n if(showMembersCount && ((peer as Chat.channel).participants_count || (peer as any).participants)) {\n const regExp = new RegExp(`(${escapeRegExp(query)}|${escapeRegExp(cleanSearchText(query))})`, 'gi');\n dom.titleSpan.innerHTML = dom.titleSpan.innerHTML.replace(regExp, '<i>$1</i>');\n dom.lastMessageSpan.append(await getChatMembersString(peerId.toChatId()));\n } else if(peerId === rootScope.myId) {\n dom.lastMessageSpan.append(i18n('Presence.YourChat'));\n } else {\n let username = await this.managers.appPeersManager.getPeerUsername(peerId);\n if(!username) {\n const user = await this.managers.appUsersManager.getUser(peerId);\n if(user && user.phone) {\n username = '+' + formatPhoneNumber(user.phone).formatted;\n }\n } else {\n username = '@' + username;\n }\n\n dom.lastMessageSpan.textContent = username;\n }\n });\n\n group.toggle();\n };\n\n const onLoad = <T>(arg: T) => {\n if(!middleware()) {\n return;\n }\n\n // this.loadedContacts = true;\n\n return arg;\n };\n\n return Promise.all([\n this.managers.appUsersManager.getContactsPeerIds(query, true, undefined, 10)\n .then(onLoad)\n .then((contacts) => {\n if(contacts) {\n setResults(contacts, this.searchGroups.contacts, true);\n }\n }),\n\n this.managers.appUsersManager.searchContacts(query, 20)\n .then(onLoad)\n .then((contacts) => {\n if(contacts) {\n setResults(contacts.my_results, this.searchGroups.contacts, true);\n setResults(contacts.results/* .concat(contacts.results, contacts.results, contacts.results) */, this.searchGroups.globalContacts);\n\n this.searchGroups.globalContacts.container.classList.add('is-short');\n\n if(this.searchGroups.globalContacts.nameEl.lastElementChild !== this.searchGroups.globalContacts.nameEl.firstElementChild) {\n this.searchGroups.globalContacts.nameEl.lastElementChild.remove();\n }\n\n if(this.searchGroups.globalContacts.list.childElementCount > 3) {\n const showMore = document.createElement('div');\n showMore.classList.add('search-group__show-more');\n const intlElement = new I18n.IntlElement({\n key: 'Separator.ShowMore'\n });\n showMore.append(intlElement.element);\n this.searchGroups.globalContacts.nameEl.append(showMore);\n attachClickEvent(showMore, () => {\n const isShort = this.searchGroups.globalContacts.container.classList.toggle('is-short');\n intlElement.key = isShort ? 'Separator.ShowMore' : 'Separator.ShowLess';\n intlElement.update();\n });\n }\n }\n }),\n\n this.managers.dialogsStorage.getDialogs({query, offsetIndex: 0, limit: 20, filterId: 0})\n .then(onLoad)\n .then((value) => {\n if(value) {\n setResults(value.dialogs.map((d) => d.peerId), this.searchGroups.contacts, true);\n }\n })\n ]);\n } else if(!this.searchContext.peerId && !this.searchContext.minDate) {\n const renderRecentSearch = (setActive = true) => {\n return apiManagerProxy.getState().then((state) => {\n if(!middleware()) {\n return;\n }\n\n this.searchGroups.recent.list.replaceChildren();\n\n state.recentSearch.slice(0, 20).forEach(async(peerId) => {\n const {dom} = appDialogsManager.addDialogNew({\n peerId: peerId,\n container: this.searchGroups.recent.list,\n meAsSaved: true,\n avatarSize: 'abitbigger',\n autonomous: true\n });\n\n dom.lastMessageSpan.append(await (peerId.isUser() ?\n getUserStatusString(await this.managers.appUsersManager.getUser(peerId.toUserId())) :\n getChatMembersString(peerId.toChatId())));\n });\n\n if(!state.recentSearch.length) {\n this.searchGroups.recent.clear();\n } else if(setActive) {\n this.searchGroups.recent.setActive();\n }\n });\n };\n\n return Promise.all([\n this.managers.appUsersManager.getTopPeers('correspondents').then((peers) => {\n if(!middleware()) return;\n\n const idx = peers.findIndex((peer) => peer.id === rootScope.myId);\n if(idx !== -1) {\n peers = peers.slice();\n peers.splice(idx, 1);\n }\n\n peers.forEach((peer) => {\n const {dom} = appDialogsManager.addDialogNew({\n peerId: peer.id,\n container: this.searchGroups.people.list,\n onlyFirstName: true,\n avatarSize: 'bigger',\n autonomous: false,\n noIcons: this.searchGroups.people.noIcons\n });\n\n dom.subtitleEl.remove();\n });\n\n this.searchGroups.people.toggle();\n }),\n\n renderRecentSearch()\n ]);\n } else return Promise.resolve();\n }\n\n private async loadMembers(mediaTab: SearchSuperMediaTab) {\n const chatId = mediaTab.type === 'members' ? this.searchContext.peerId.toChatId() : undefined;\n const userId = mediaTab.type === 'groups' ? this.searchContext.peerId.toUserId() : undefined;\n const middleware = this.middleware.get();\n let promise: Promise<void>;\n\n const renderParticipants = async(participants: (ChatParticipant | ChannelParticipant | Chat)[]) => {\n if(this.loadMutex) {\n await this.loadMutex;\n\n if(!middleware()) {\n return;\n }\n }\n\n let membersList = this.membersList;\n if(!membersList) {\n membersList = this.membersList = new SortedUserList({\n lazyLoadQueue: this.lazyLoadQueue,\n rippleEnabled: false,\n managers: this.managers\n });\n attachClickEvent(membersList.list, (e) => {\n const li = findUpTag(e.target, DIALOG_LIST_ELEMENT_TAG);\n if(!li) {\n return;\n }\n\n const peerId = li.dataset.peerId.toPeerId();\n let promise: Promise<any> = Promise.resolve();\n if(mediaSizes.isMobile) {\n promise = appSidebarRight.toggleSidebar(false);\n }\n\n promise.then(() => {\n appImManager.setInnerPeer({peerId});\n });\n });\n mediaTab.contentTab.append(membersList.list);\n this.afterPerforming(1, mediaTab.contentTab);\n }\n\n const peerIds: {peerId: PeerId, rank: ReturnType<typeof getParticipantRank>}[] = participants.map((participant) => {\n const peerId = userId ? (participant as Chat.chat).id.toPeerId(true) : getParticipantPeerId(participant as ChannelParticipant);\n if(chatId ? peerId.isAnyChat() : peerId.isUser()) {\n return;\n }\n\n return {\n peerId,\n rank: getParticipantRank(participant as ChannelParticipant) as any\n };\n }).filter(Boolean);\n\n const filtered = await filterAsync(peerIds, async({peerId}) => {\n const peer: User | Chat = await this.managers.appPeersManager.getPeer(peerId);\n if(!middleware()) {\n return false;\n }\n\n if(!peer || (peer as User.user).pFlags.deleted) {\n return false;\n }\n\n return true;\n });\n\n for(const {peerId, rank} of filtered) {\n if(rank) {\n membersList.ranks.set(peerId, rank);\n }\n\n membersList.add(peerId);\n }\n };\n\n if(userId) {\n const LOAD_COUNT = !this.membersList ? 50 : 200;\n promise = this.managers.appUsersManager.getCommonChats(userId, LOAD_COUNT, this.nextRates[mediaTab.inputFilter]).then((messagesChats) => {\n if(!middleware()) {\n return;\n }\n\n // const list = mediaTab.contentTab.firstElementChild as HTMLUListElement;\n const lastChat = messagesChats.chats[messagesChats.chats.length - 1];\n this.nextRates[mediaTab.inputFilter] = lastChat?.id as number;\n\n if(messagesChats.chats.length < LOAD_COUNT) {\n this.loaded[mediaTab.inputFilter] = true;\n }\n\n return renderParticipants(messagesChats.chats);\n });\n } else if(await this.managers.appChatsManager.isChannel(chatId)) {\n const LOAD_COUNT = !this.membersList ? 50 : 200;\n promise = this.managers.appProfileManager.getChannelParticipants(chatId, undefined, LOAD_COUNT, this.nextRates[mediaTab.inputFilter]).then((participants) => {\n if(!middleware()) {\n return;\n }\n\n const list = mediaTab.contentTab.firstElementChild as HTMLUListElement;\n this.nextRates[mediaTab.inputFilter] = (list ? list.childElementCount : 0) + participants.participants.length;\n\n if(participants.participants.length < LOAD_COUNT) {\n this.loaded[mediaTab.inputFilter] = true;\n }\n\n return renderParticipants(participants.participants);\n });\n } else {\n promise = this.managers.appProfileManager.getChatFull(chatId).then((chatFull) => {\n if(!middleware()) {\n return;\n }\n\n // console.log('anymore', chatFull);\n this.loaded[mediaTab.inputFilter] = true;\n const participants = (chatFull as ChatFull.chatFull).participants;\n if(participants._ === 'chatParticipantsForbidden') {\n return;\n }\n\n return renderParticipants(participants.participants);\n });\n }\n\n return this.loadPromises[mediaTab.inputFilter] = promise.finally(() => {\n if(!middleware()) {\n return;\n }\n\n this.loadPromises[mediaTab.inputFilter] = null;\n });\n }\n\n private loadType(mediaTab: SearchSuperMediaTab, justLoad: boolean, loadCount: number, middleware: () => boolean) {\n const type = mediaTab.inputFilter;\n\n if(this.loadPromises[type]) {\n return this.loadPromises[type];\n }\n\n if(mediaTab.type === 'members' || mediaTab.type === 'groups') {\n return this.loadMembers(mediaTab);\n }\n\n const history = this.historyStorage[type] ??= [];\n\n if(type === 'inputMessagesFilterEmpty' && !history.length) {\n if(!this.loadedChats) {\n this.loadChats();\n this.loadedChats = true;\n }\n\n if(!this.searchContext.query.trim() && !this.searchContext.peerId && !this.searchContext.minDate) {\n this.loaded[type] = true;\n return Promise.resolve();\n }\n }\n\n const promise = this.loadPromises[type] = Promise.resolve().then(async() => {\n // render from cache\n if(history.length && this.usedFromHistory[type] < history.length && !justLoad) {\n const messages: any[] = [];\n let used = Math.max(0, this.usedFromHistory[type]);\n let slicedLength = 0;\n\n do {\n const ids = history.slice(used, used + loadCount);\n used += ids.length;\n slicedLength += ids.length;\n\n const notFilteredMessages = await Promise.all(ids.map((m) => this.managers.appMessagesManager.getMessageByPeer(m.peerId, m.mid)));\n\n messages.push(...this.filterMessagesByType(notFilteredMessages, type));\n } while(slicedLength < loadCount && used < history.length);\n\n // если перебор\n /* if(slicedLength > loadCount) {\n let diff = messages.length - loadCount;\n messages = messages.slice(0, messages.length - diff);\n used -= diff;\n } */\n\n this.usedFromHistory[type] = used;\n // if(messages.length) {\n return this.performSearchResult(messages, mediaTab).finally(() => {\n setTimeout(() => {\n this.scrollable.checkForTriggers();\n }, 0);\n });\n // }\n }\n\n const maxId = history.length ? history[history.length - 1].mid : 0;\n\n const value = await this.managers.appMessagesManager.getSearch({\n ...this.searchContext,\n inputFilter: {_: type},\n maxId,\n limit: loadCount,\n nextRate: this.nextRates[type] ??= 0\n });\n\n history.push(...value.history.map((m) => ({mid: m.mid, peerId: m.peerId})));\n\n if(!middleware()) {\n // this.log.warn('peer changed');\n return;\n }\n\n // ! Фикс случая, когда не загружаются документы при открытой панели разработчиков (происходит из-за того, что не совпадают критерии отбора документов в getSearch)\n if(value.history.length < loadCount || (this.searchContext.folderId !== undefined && !value.next_rate) || value.history.length === value.count) {\n // if((value.count || history.length === value.count) && history.length >= value.count) {\n // this.log(logStr + 'loaded all media', value, loadCount);\n this.loaded[type] = true;\n }\n\n this.nextRates[type] = value.next_rate;\n\n if(justLoad) {\n return;\n }\n\n this.usedFromHistory[type] = history.length;\n\n if(!this.loaded[type]) {\n promise.then(() => {\n setTimeout(() => {\n if(!middleware()) return;\n // this.log('will preload more');\n if(this.mediaTab === mediaTab) {\n const promise = this.load(true, true);\n if(promise) {\n promise.then(() => {\n if(!middleware()) return;\n // this.log('preloaded more');\n setTimeout(() => {\n this.scrollable.checkForTriggers();\n }, 0);\n });\n }\n }\n }, 0);\n });\n }\n\n // if(value.history.length) {\n return this.performSearchResult(this.filterMessagesByType(value.history, type), mediaTab);\n // }\n }).catch((err) => {\n this.log.error('load error:', err);\n }).finally(() => {\n this.loadPromises[type] = null;\n });\n\n return promise;\n }\n\n private canLoadMediaTab(mediaTab: SearchSuperMediaTab) {\n const inputFilter = mediaTab.inputFilter;\n return !this.loaded[inputFilter] || (this.historyStorage[inputFilter] && this.usedFromHistory[inputFilter] < this.historyStorage[inputFilter].length);\n }\n\n private async loadFirstTime() {\n const middleware = this.middleware.get();\n const {peerId, threadId} = this.searchContext;\n if(!this.hideEmptyTabs) {\n return;\n }\n\n const mediaTabs = this.mediaTabs.filter((mediaTab) => mediaTab.inputFilter !== 'inputMessagesFilterEmpty');\n const filters = mediaTabs.map((mediaTab) => ({_: mediaTab.inputFilter}));\n\n const [counters, canViewMembers, canViewGroups] = await Promise.all([\n this.managers.appMessagesManager.getSearchCounters(peerId, filters, undefined, threadId),\n this.canViewMembers(),\n this.canViewGroups()\n ]);\n\n if(!middleware()) {\n return;\n }\n\n if(this.loadMutex) {\n await this.loadMutex;\n\n if(!middleware()) {\n return;\n }\n }\n\n let firstMediaTab: SearchSuperMediaTab;\n let count = 0;\n mediaTabs.forEach((mediaTab) => {\n const counter = counters.find((c) => c.filter._ === mediaTab.inputFilter);\n\n mediaTab.menuTab.classList.toggle('hide', !counter.count);\n mediaTab.menuTab.classList.remove('active');\n // mediaTab.contentTab.classList.toggle('hide', !counter.count);\n\n if(counter.count) {\n if(firstMediaTab === undefined) {\n firstMediaTab = mediaTab;\n }\n\n ++count;\n }\n });\n\n const membersTab = this.mediaTabsMap.get('members');\n\n const a: [SearchSuperMediaTab, boolean][] = [\n [membersTab, canViewMembers],\n [this.mediaTabsMap.get('groups'), canViewGroups]\n ];\n\n a.forEach(([tab, value]) => {\n if(!tab) {\n return;\n }\n\n tab.menuTab.classList.toggle('hide', !value);\n\n if(value) {\n ++count;\n }\n });\n\n if(canViewMembers) {\n firstMediaTab = membersTab;\n }\n\n this.container.classList.toggle('hide', !firstMediaTab);\n this.container.parentElement.classList.toggle('search-empty', !firstMediaTab);\n if(firstMediaTab) {\n this.skipScroll = true;\n this.selectTab(this.mediaTabs.indexOf(firstMediaTab), false);\n // firstMediaTab.menuTab.classList.add('active');\n\n this.navScrollableContainer.classList.toggle('hide', count <= 1);\n }\n }\n\n public async load(single = false, justLoad = false) {\n const peerId = this.searchContext.peerId;\n this.log('load', single, peerId, this.loadPromises);\n const middleware = this.middleware.get();\n\n if(this.firstLoad) {\n await (this.loadFirstTimePromise ??= this.loadFirstTime());\n if(!middleware()) {\n return;\n }\n\n this.loadFirstTimePromise = undefined;\n this.firstLoad = false;\n }\n\n let toLoad = single ? [this.mediaTab] : this.mediaTabs.filter((t) => t !== this.mediaTab);\n toLoad = toLoad.filter((mediaTab) => {\n return this.canLoadMediaTab(mediaTab);\n });\n\n if(peerId.isUser()) {\n findAndSplice(toLoad, (mediaTab) => mediaTab.type === 'members');\n } else {\n findAndSplice(toLoad, (mediaTab) => mediaTab.type === 'groups');\n }\n\n if(!toLoad.length) {\n return;\n }\n\n const loadCount = justLoad ? 50 : Math.round((windowSize.height / 130 | 0) * 3 * 1.25); // that's good for all types\n\n const promises: Promise<any>[] = toLoad.map((mediaTab) => {\n return this.loadType(mediaTab, justLoad, loadCount, middleware);\n });\n\n return Promise.all(promises).catch((err) => {\n this.log.error('Load error all promises:', err);\n });\n }\n\n private getMonthContainerByTimestamp(timestamp: number, type: SearchSuperType) {\n const date = new Date(timestamp * 1000);\n date.setHours(0, 0, 0);\n date.setDate(1);\n const dateTimestamp = date.getTime();\n const containers = this.monthContainers[type] ?? (this.monthContainers[type] = {});\n if(!(dateTimestamp in containers)) {\n const container = document.createElement('div');\n container.className = 'search-super-month';\n\n const name = document.createElement('div');\n name.classList.add('search-super-month-name');\n\n const options: Intl.DateTimeFormatOptions = {\n month: 'long'\n };\n\n if(date.getFullYear() !== new Date().getFullYear()) {\n options.year = 'numeric';\n }\n\n const dateElement = new I18n.IntlDateElement({\n date,\n options\n }).element;\n name.append(dateElement);\n\n container.append(name);\n\n const items = document.createElement('div');\n items.classList.add('search-super-month-items');\n\n container.append(name, items);\n\n const haveTimestamps = getObjectKeysAndSort(containers, 'desc');\n let i = 0;\n for(; i < haveTimestamps.length; ++i) {\n const t = haveTimestamps[i];\n if(dateTimestamp > t) {\n break;\n }\n }\n\n containers[dateTimestamp] = {container, items};\n positionElementByIndex(container, this.tabs[type], i);\n }\n\n return containers[dateTimestamp];\n }\n\n public canViewMembers() {\n const {peerId} = this.searchContext;\n const isAnyChat = peerId.isAnyChat();\n if(!isAnyChat || !this.mediaTabsMap.has('members')) return Promise.resolve(false);\n const chatId = peerId.toChatId();\n return Promise.all([\n this.managers.appChatsManager.isBroadcast(chatId),\n this.managers.appChatsManager.hasRights(chatId, 'view_participants'),\n this.managers.appChatsManager.isForum(chatId)\n ]).then(([isBroadcast, hasRights, isForum]) => {\n return !isBroadcast && hasRights && (!this.searchContext.threadId || !isForum);\n });\n }\n\n public async canViewGroups() {\n const {peerId} = this.searchContext;\n if(!peerId.isUser() || !this.mediaTabsMap.has('groups')) return false;\n const userFull = await this.managers.appProfileManager.getProfile(peerId.toUserId());\n return !!userFull.common_chats_count;\n }\n\n public cleanup() {\n this.loadPromises = {};\n this.loaded = {};\n this.loadedChats = false;\n this.nextRates = {};\n this.firstLoad = true;\n this.prevTabId = -1;\n\n this.lazyLoadQueue.clear();\n\n this.mediaTabs.forEach((mediaTab) => {\n this.usedFromHistory[mediaTab.inputFilter] = -1;\n });\n\n if(this.selection?.isSelecting) {\n this.selection.cancelSelection();\n }\n\n // * must go to first tab (это костыль)\n /* const membersTab = this.mediaTabsMap.get('members');\n if(membersTab) {\n const tab = this.canViewMembers() ? membersTab : this.mediaTabs[this.mediaTabs.indexOf(membersTab) + 1];\n this.mediaTab = tab;\n } */\n\n this.middleware.clean();\n this.loadFirstTimePromise = undefined;\n this.cleanScrollPositions();\n this.membersList = undefined;\n }\n\n public cleanScrollPositions() {\n this.mediaTabs.forEach((mediaTab) => {\n mediaTab.scroll = undefined;\n });\n }\n\n public cleanupHTML(goFirst = false) {\n this.mediaTabs.forEach((tab) => {\n tab.contentTab.replaceChildren();\n\n if(this.hideEmptyTabs) {\n // tab.menuTab.classList.add('hide');\n this.container.classList.add('hide');\n this.container.parentElement.classList.add('search-empty');\n }\n\n if(tab.type === 'chats') {\n return;\n }\n\n if(!this.historyStorage[tab.inputFilter]) {\n const parent = tab.contentTab.parentElement;\n // if(!testScroll) {\n if(!parent.querySelector('.preloader')) {\n putPreloader(parent, true);\n }\n // }\n\n const empty = parent.querySelector('.content-empty');\n if(empty) {\n empty.remove();\n }\n }\n });\n\n /* if(goFirst) {\n const membersTab = this.mediaTabsMap.get('members');\n if(membersTab) {\n let idx = this.canViewMembers() ? 0 : 1;\n membersTab.menuTab.classList.toggle('hide', idx !== 0);\n\n this.selectTab(idx, false);\n } else {\n this.selectTab(0, false);\n }\n } */\n\n this.monthContainers = {};\n this.searchGroupMedia.clear();\n this.scrollable.scrollTop = 0;\n\n /* if(testScroll) {\n for(let i = 0; i < 1500; ++i) {\n let div = document.createElement('div');\n div.insertAdjacentHTML('beforeend', `<img class=\"media-image\" src=\"assets/img/camomile.jpg\">`);\n div.classList.add('grid-item');\n div.dataset.id = '' + (i / 3 | 0);\n //div.innerText = '' + (i / 3 | 0);\n this.tabs.inputMessagesFilterPhotoVideo.append(div);\n }\n } */\n }\n\n private copySearchContext(newInputFilter: MyInputMessagesFilter) {\n const context = copy(this.searchContext);\n context.inputFilter = {_: newInputFilter};\n context.nextRate = this.nextRates[newInputFilter];\n return context;\n }\n\n public setQuery({peerId, query, threadId, historyStorage, folderId, minDate, maxDate}: {\n peerId: PeerId,\n query?: string,\n threadId?: number,\n historyStorage?: AppSearchSuper['historyStorage'],\n folderId?: number,\n minDate?: number,\n maxDate?: number\n }) {\n this.searchContext = {\n peerId,\n query: query || '',\n inputFilter: {_: this.mediaTab.inputFilter},\n threadId,\n folderId,\n minDate,\n maxDate\n };\n\n this.historyStorage = historyStorage ?? {};\n\n this.cleanup();\n }\n\n public destroy() {\n this.cleanup();\n this.listenerSetter.removeAll();\n this.scrollable.destroy();\n this.swipeHandler?.removeListeners();\n this.selection?.cleanup();\n\n this.scrollStartCallback = undefined;\n this.onChangeTab = undefined;\n this.selectTab = undefined;\n this.searchContextMenu = undefined;\n this.swipeHandler = undefined;\n this.selection = undefined;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport cancelEvent from './cancelEvent';\n\nexport default function lockTouchScroll(container: HTMLElement) {\n const onTouchMove = (e: TouchEvent) => {\n cancelEvent(e);\n };\n\n let lockers = 2;\n const cb = () => {\n if(!--lockers) {\n container.removeEventListener('touchmove', onTouchMove, {capture: true});\n }\n };\n\n container.addEventListener('touchmove', onTouchMove, {capture: true, passive: false});\n container.addEventListener('touchend', cb, {once: true});\n\n return cb;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {ChatRights} from '../lib/appManagers/appChatsManager';\nimport type {Dialog} from '../lib/appManagers/appMessagesManager';\nimport appDialogsManager, {DialogElementSize as DialogElementSize} from '../lib/appManagers/appDialogsManager';\nimport rootScope from '../lib/rootScope';\nimport Scrollable from './scrollable';\nimport {FocusDirection} from '../helpers/fastSmoothScroll';\nimport CheckboxField from './checkboxField';\nimport {i18n, LangPackKey, _i18n} from '../lib/langPack';\nimport findUpAttribute from '../helpers/dom/findUpAttribute';\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport PeerTitle from './peerTitle';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport debounce from '../helpers/schedulers/debounce';\nimport windowSize from '../helpers/windowSize';\nimport type {IsPeerType} from '../lib/appManagers/appPeersManager';\nimport {attachClickEvent, simulateClickEvent} from '../helpers/dom/clickEvent';\nimport filterUnique from '../helpers/array/filterUnique';\nimport indexOfAndSplice from '../helpers/array/indexOfAndSplice';\nimport safeAssign from '../helpers/object/safeAssign';\nimport findAndSplice from '../helpers/array/findAndSplice';\nimport AvatarElement from './avatar';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport filterAsync from '../helpers/array/filterAsync';\nimport getParticipantPeerId from '../lib/appManagers/utils/chats/getParticipantPeerId';\nimport getChatMembersString from './wrappers/getChatMembersString';\nimport getUserStatusString from './wrappers/getUserStatusString';\nimport {ChannelsChannelParticipants, Chat, User} from '../layer';\nimport canSendToUser from '../lib/appManagers/utils/users/canSendToUser';\nimport hasRights from '../lib/appManagers/utils/chats/hasRights';\nimport getDialogIndex from '../lib/appManagers/utils/dialogs/getDialogIndex';\nimport {generateDelimiter} from './generateDelimiter';\nimport SettingSection from './settingSection';\nimport liteMode from '../helpers/liteMode';\n\ntype SelectSearchPeerType = 'contacts' | 'dialogs' | 'channelParticipants';\n\n// TODO: правильная сортировка для addMembers, т.е. для peerType: 'contacts', потому что там идут сначала контакты - потом неконтакты, а должно всё сортироваться по имени\n\nexport default class AppSelectPeers {\n public container = document.createElement('div');\n public list = appDialogsManager.createChatList(/* {\n handheldsSize: 66,\n avatarSize: 48\n } */);\n private chatsContainer = document.createElement('div');\n public scrollable: Scrollable;\n private selectedScrollable: Scrollable;\n\n private selectedContainer: HTMLElement;\n public input: HTMLInputElement;\n\n // public selected: {[peerId: PeerId]: HTMLElement} = {};\n public selected = new Set<PeerId | string>();\n\n public freezed = false;\n\n private folderId = 0;\n private offsetIndex = 0;\n private promise: Promise<any>;\n\n private query = '';\n private cachedContacts: PeerId[];\n\n private loadedWhat: Partial<{[k in 'dialogs' | 'archived' | 'contacts' | 'channelParticipants']: true}> = {};\n\n private renderedPeerIds: Set<PeerId> = new Set();\n\n private appendTo: HTMLElement;\n private onChange: (length: number) => void;\n private peerType: SelectSearchPeerType[] = ['dialogs'];\n private renderResultsFunc: (peerIds: PeerId[]) => void | Promise<void>;\n private chatRightsActions: ChatRights[];\n private multiSelect = true;\n private rippleEnabled = true;\n private avatarSize: DialogElementSize = 'abitbigger';\n private exceptSelf = false;\n private filterPeerTypeBy: IsPeerType[];\n\n private tempIds: {[k in keyof AppSelectPeers['loadedWhat']]: number} = {};\n private peerId: PeerId;\n\n private placeholder: LangPackKey;\n\n private selfPresence: LangPackKey = 'Presence.YourChat';\n\n private needSwitchList = false;\n\n private sectionNameLangPackKey: LangPackKey;\n\n private managers: AppManagers;\n\n private design: 'round' | 'square' = 'round';\n\n constructor(options: {\n appendTo: AppSelectPeers['appendTo'],\n onChange?: AppSelectPeers['onChange'],\n peerType?: AppSelectPeers['peerType'],\n peerId?: AppSelectPeers['peerId'],\n onFirstRender?: () => void,\n renderResultsFunc?: AppSelectPeers['renderResultsFunc'],\n chatRightsActions?: AppSelectPeers['chatRightsActions'],\n multiSelect?: AppSelectPeers['multiSelect'],\n rippleEnabled?: AppSelectPeers['rippleEnabled'],\n avatarSize?: AppSelectPeers['avatarSize'],\n placeholder?: AppSelectPeers['placeholder'],\n selfPresence?: AppSelectPeers['selfPresence'],\n exceptSelf?: AppSelectPeers['exceptSelf'],\n filterPeerTypeBy?: AppSelectPeers['filterPeerTypeBy'],\n sectionNameLangPackKey?: AppSelectPeers['sectionNameLangPackKey'],\n managers: AppSelectPeers['managers'],\n design?: AppSelectPeers['design']\n }) {\n safeAssign(this, options);\n\n this.container.classList.add('selector', 'selector-' + this.design);\n\n const f = (this.renderResultsFunc || this.renderResults).bind(this);\n this.renderResultsFunc = async(peerIds) => {\n if(this.needSwitchList) {\n this.scrollable.splitUp.replaceWith(this.list);\n this.scrollable.setVirtualContainer(this.list);\n this.needSwitchList = false;\n }\n\n peerIds = peerIds.filter((peerId) => {\n const notRendered = !this.renderedPeerIds.has(peerId);\n if(notRendered) this.renderedPeerIds.add(peerId);\n return notRendered;\n });\n\n if(this.filterPeerTypeBy) {\n peerIds = await filterAsync(peerIds, async(peerId) => {\n if(peerId.isPeerId()) {\n const peer = await this.managers.appPeersManager.getPeer(peerId);\n if(peer) {\n for(const method of this.filterPeerTypeBy) {\n if(await this.managers.appPeersManager[method](peerId)) {\n return true;\n }\n }\n }\n }\n\n return true;\n });\n }\n\n return f(peerIds);\n };\n\n this.input = document.createElement('input');\n this.input.classList.add('selector-search-input');\n if(this.placeholder) {\n _i18n(this.input, this.placeholder, undefined, 'placeholder');\n } else {\n _i18n(this.input, 'SendMessageTo', undefined, 'placeholder');\n }\n\n this.input.type = 'text';\n\n if(this.multiSelect) {\n const section = new SettingSection({});\n section.innerContainer.classList.add('selector-search-section');\n const topContainer = document.createElement('div');\n topContainer.classList.add('selector-search-container');\n\n this.selectedContainer = document.createElement('div');\n this.selectedContainer.classList.add('selector-search');\n\n this.selectedContainer.append(this.input);\n topContainer.append(this.selectedContainer);\n this.selectedScrollable = new Scrollable(topContainer);\n\n // let delimiter = document.createElement('hr');\n\n attachClickEvent(this.selectedContainer, (e) => {\n if(this.freezed) return;\n let target = e.target as HTMLElement;\n target = findUpClassName(target, 'selector-user');\n\n if(!target) return;\n\n const peerId = target.dataset.key;\n const li = this.chatsContainer.querySelector('[data-peer-id=\"' + peerId + '\"]') as HTMLElement;\n if(!li) {\n this.remove(peerId.toPeerId());\n } else {\n simulateClickEvent(li);\n }\n });\n\n section.content.append(topContainer);\n this.container.append(section.container/* , delimiter */);\n }\n\n this.chatsContainer.classList.add('chatlist-container');\n // this.chatsContainer.append(this.list);\n const section = new SettingSection({\n name: this.sectionNameLangPackKey,\n noShadow: true\n });\n section.content.append(this.list);\n this.chatsContainer.append(section.container);\n this.scrollable = new Scrollable(this.chatsContainer);\n this.scrollable.setVirtualContainer(this.list);\n\n attachClickEvent(this.chatsContainer, (e) => {\n const target = findUpAttribute(e.target, 'data-peer-id') as HTMLElement;\n cancelEvent(e);\n\n if(!target) return;\n if(this.freezed) return;\n\n let key: PeerId | string = target.dataset.peerId;\n key = key.isPeerId() ? key.toPeerId() : key;\n\n if(!this.multiSelect) {\n this.add(key);\n return;\n }\n\n // target.classList.toggle('active');\n if(this.selected.has(key)) {\n this.remove(key);\n } else {\n this.add(key);\n }\n\n const checkbox = target.querySelector('input') as HTMLInputElement;\n checkbox.checked = !checkbox.checked;\n });\n\n const debouncedInput = debounce(this.onInput, 200, false, true);\n this.input.addEventListener('input', debouncedInput);\n\n this.scrollable.onScrolledBottom = () => {\n this.getMoreResults();\n };\n\n this.scrollable.container.prepend(generateDelimiter());\n\n this.container.append(this.chatsContainer);\n this.appendTo.append(this.container);\n\n // WARNING TIMEOUT\n setTimeout(() => {\n const getResultsPromise = this.getMoreResults() as Promise<any>;\n if(options.onFirstRender) {\n getResultsPromise.then(() => {\n options.onFirstRender();\n });\n }\n }, 0);\n }\n\n private onInput = () => {\n const value = this.input.value;\n if(this.query !== value) {\n if(this.peerType.includes('contacts') || this.peerType.includes('dialogs')) {\n this.cachedContacts = undefined;\n }\n\n if(this.peerType.includes('dialogs')) {\n this.folderId = 0;\n this.offsetIndex = 0;\n }\n\n for(const i in this.tempIds) {\n // @ts-ignore\n ++this.tempIds[i];\n }\n\n this.list = appDialogsManager.createChatList();\n\n this.promise = undefined;\n this.loadedWhat = {};\n this.query = value;\n this.renderedPeerIds.clear();\n this.needSwitchList = true;\n\n // console.log('selectPeers input:', this.query);\n this.getMoreResults();\n }\n };\n\n private async renderSaved() {\n if(\n !this.exceptSelf &&\n !this.offsetIndex &&\n this.folderId === 0 &&\n this.peerType.includes('dialogs') &&\n (!this.query || await this.managers.appUsersManager.testSelfSearch(this.query))\n ) {\n await this.renderResultsFunc([rootScope.myId]);\n }\n }\n\n private getTempId(type: keyof AppSelectPeers['tempIds']) {\n this.tempIds[type] ??= 0;\n const tempId = ++this.tempIds[type];\n return {\n tempId,\n middleware: () => this.tempIds[type] === tempId\n };\n }\n\n private async getMoreDialogs(): Promise<any> {\n if(this.loadedWhat.dialogs && this.loadedWhat.archived) {\n return;\n }\n\n // в десктопе - сначала без группы, потом архивные, потом контакты без сообщений\n const pageCount = windowSize.height / 56 * 1.25 | 0;\n\n const {middleware} = this.getTempId('dialogs');\n const promise = this.managers.dialogsStorage.getDialogs({\n query: this.query,\n offsetIndex: this.offsetIndex,\n limit: pageCount,\n filterId: this.folderId,\n skipMigrated: true\n });\n\n promise.catch(() => {\n if(!middleware()) {\n return;\n }\n\n this.loadedWhat[this.loadedWhat.dialogs ? 'archived' : 'dialogs'] = true;\n });\n\n const value = await promise;\n if(!middleware()) {\n return;\n }\n\n let dialogs = value.dialogs as Dialog[];\n if(dialogs.length) {\n const newOffsetIndex = getDialogIndex(dialogs[dialogs.length - 1]) || 0;\n\n dialogs = dialogs.slice();\n findAndSplice(dialogs, d => d.peerId === rootScope.myId); // no my account\n\n if(this.chatRightsActions) {\n dialogs = await filterAsync(dialogs, (d) => this.filterByRights(d.peerId));\n if(!middleware()) {\n return;\n }\n }\n\n await this.renderSaved();\n if(!middleware()) {\n return;\n }\n\n this.offsetIndex = newOffsetIndex;\n }\n\n this.renderResultsFunc(dialogs.map((dialog) => dialog.peerId));\n\n if(value.isEnd) {\n if(!this.loadedWhat.dialogs) {\n await this.renderSaved();\n if(!middleware()) {\n return;\n }\n\n this.loadedWhat.dialogs = true;\n this.offsetIndex = 0;\n this.folderId = 1;\n\n return this.getMoreDialogs();\n } else {\n this.loadedWhat.archived = true;\n\n if(!this.loadedWhat.contacts/* && this.peerType.includes('contacts') */) {\n return this.getMoreContacts();\n }\n }\n }\n }\n\n private async filterByRights(peerId: PeerId) {\n const peer: User | Chat = await this.managers.appPeersManager.getPeer(peerId);\n if(peerId.isUser()) {\n return this.chatRightsActions[0] !== 'send_plain' || canSendToUser(peer as User.user);\n } else if(this.chatRightsActions.every((action) => hasRights(peer as Chat.chat, action))) {\n return true;\n }\n }\n\n private async getMoreContacts() {\n if(this.loadedWhat.contacts) {\n return;\n }\n\n const isGlobalSearch = this.peerType.includes('contacts');\n\n if(!this.cachedContacts) {\n /* const promises: Promise<any>[] = [appUsersManager.getContacts(this.query)];\n if(!this.peerType.includes('dialogs')) {\n promises.push(appMessagesManager.getConversationsAll());\n }\n\n this.promise = Promise.all(promises);\n this.cachedContacts = (await this.promise)[0].slice(); */\n const {middleware} = this.getTempId('contacts');\n const promise = Promise.all([\n isGlobalSearch ? this.managers.appUsersManager.getContactsPeerIds(this.query) : [],\n this.query ? this.managers.appUsersManager.searchContacts(this.query) : undefined\n ]);\n\n promise.catch(() => {\n if(!middleware()) {\n return;\n }\n\n this.loadedWhat.contacts = true;\n });\n\n const [cachedContacts, searchResult] = await promise;\n if(!middleware()) {\n return;\n }\n\n if(searchResult) {\n // do not add global result if only dialogs needed\n let resultPeerIds = isGlobalSearch ? searchResult.my_results.concat(searchResult.results) : searchResult.my_results;\n\n if(this.chatRightsActions) {\n resultPeerIds = await filterAsync(resultPeerIds, (peerId) => this.filterByRights(peerId));\n if(!middleware()) {\n return;\n }\n }\n\n if(!this.peerType.includes('dialogs')) {\n resultPeerIds = resultPeerIds.filter((peerId) => peerId.isUser());\n }\n\n this.cachedContacts = filterUnique(cachedContacts.concat(resultPeerIds));\n } else this.cachedContacts = cachedContacts.slice();\n\n indexOfAndSplice(this.cachedContacts, rootScope.myId); // no my account\n }\n\n // if(this.cachedContacts.length) {\n const pageCount = windowSize.height / 56 * 1.25 | 0;\n const arr = this.cachedContacts.splice(0, pageCount);\n this.renderResultsFunc(arr);\n // }\n\n if(!this.cachedContacts.length) {\n this.loadedWhat.contacts = true;\n\n // need to load non-contacts\n /* if(!this.peerType.includes('dialogs')) {\n return this.getMoreDialogs();\n } */\n }\n }\n\n private async getMoreChannelParticipants() {\n if(this.loadedWhat.channelParticipants) {\n return;\n }\n\n const pageCount = 50; // same as in group permissions to use cache\n\n const {middleware} = this.getTempId('channelParticipants');\n const promise = this.managers.appProfileManager.getParticipants(\n this.peerId.toChatId(),\n {\n _: 'channelParticipantsSearch',\n q: this.query\n },\n pageCount,\n this.list.childElementCount\n );\n\n promise.catch(() => {\n if(!middleware()) {\n return;\n }\n\n this.loadedWhat.channelParticipants = true;\n });\n\n const chatParticipants = await promise;\n if(!middleware()) {\n return;\n }\n\n const {participants} = chatParticipants;\n\n const peerIds = participants.map((participant) => getParticipantPeerId(participant));\n indexOfAndSplice(peerIds, rootScope.myId);\n this.renderResultsFunc(peerIds);\n\n const count = (chatParticipants as ChannelsChannelParticipants.channelsChannelParticipants).count ?? participants.length;\n\n if(this.list.childElementCount >= count || participants.length < pageCount) {\n this.loadedWhat.channelParticipants = true;\n }\n }\n\n checkForTriggers = () => {\n this.scrollable.checkForTriggers();\n };\n\n private getMoreResults() {\n if(this.promise) {\n return this.promise;\n }\n\n const get = () => {\n if((this.peerType.includes('dialogs')/* || this.loadedWhat.contacts */) && !this.loadedWhat.archived) { // to load non-contacts\n return this.getMoreSomething('dialogs');\n }\n\n if((this.peerType.includes('contacts') || this.peerType.includes('dialogs')) && !this.loadedWhat.contacts) {\n return this.getMoreSomething('contacts');\n }\n\n if(this.peerType.includes('channelParticipants') && !this.loadedWhat.channelParticipants) {\n return this.getMoreSomething('channelParticipants');\n }\n };\n\n const loadPromise = get();\n if(!loadPromise) {\n return Promise.resolve();\n }\n\n const promise = this.promise = loadPromise.catch((err) => {\n console.error('get more result error', err);\n }).finally(() => {\n if(this.promise === promise) {\n this.promise = undefined;\n }\n\n this.checkForTriggers();\n });\n\n return promise;\n }\n\n private getMoreSomething(peerType: SelectSearchPeerType) {\n const map: {[type in SelectSearchPeerType]: () => Promise<any>} = {\n dialogs: this.getMoreDialogs,\n contacts: this.getMoreContacts,\n channelParticipants: this.getMoreChannelParticipants\n };\n\n const promise = map[peerType].call(this);\n return promise;\n }\n\n private async renderResults(peerIds: PeerId[]) {\n // console.log('will renderResults:', peerIds);\n\n // оставим только неконтакты с диалогов\n if(!this.peerType.includes('dialogs') && this.loadedWhat.contacts) {\n peerIds = await filterAsync(peerIds, (peerId) => {\n return this.managers.appUsersManager.isNonContactUser(peerId);\n });\n }\n\n peerIds.forEach(async(peerId) => {\n const {dom} = appDialogsManager.addDialogNew({\n peerId: peerId,\n container: this.scrollable,\n rippleEnabled: this.rippleEnabled,\n avatarSize: this.avatarSize\n });\n\n if(this.multiSelect) {\n const selected = this.selected.has(peerId);\n const checkboxField = new CheckboxField();\n\n if(selected) {\n // dom.listEl.classList.add('active');\n checkboxField.input.checked = true;\n }\n\n dom.containerEl.prepend(checkboxField.label);\n }\n\n let subtitleEl: HTMLElement;\n if(peerId.isAnyChat()) {\n subtitleEl = await getChatMembersString(peerId.toChatId());\n } else if(peerId === rootScope.myId) {\n subtitleEl = i18n(this.selfPresence);\n } else {\n subtitleEl = getUserStatusString(await this.managers.appUsersManager.getUser(peerId.toUserId()));\n }\n\n dom.lastMessageSpan.append(subtitleEl);\n });\n }\n\n public add(key: PeerId | string, title?: string | HTMLElement, scroll = true) {\n // console.trace('add');\n this.selected.add(key);\n\n if(!this.multiSelect) {\n this.onChange(this.selected.size);\n return;\n }\n\n if(this.query.trim()) {\n this.input.value = '';\n this.onInput();\n }\n\n const div = document.createElement('div');\n div.classList.add('selector-user', 'scale-in');\n\n const avatarEl = new AvatarElement();\n avatarEl.classList.add('selector-user-avatar', 'tgico', 'avatar-32');\n avatarEl.isDialog = true;\n\n div.dataset.key = '' + key;\n if(key.isPeerId()) {\n if(title === undefined) {\n const peerTitle = new PeerTitle();\n peerTitle.update({peerId: key.toPeerId(), dialog: true});\n title = peerTitle.element;\n }\n\n avatarEl.updateWithOptions({\n peerId: key as PeerId\n });\n }\n\n if(title) {\n if(typeof(title) === 'string') {\n div.innerHTML = title;\n } else {\n replaceContent(div, title);\n div.append(title);\n }\n }\n\n div.insertAdjacentElement('afterbegin', avatarEl);\n\n this.selectedContainer.insertBefore(div, this.input);\n // this.selectedScrollable.scrollTop = this.selectedScrollable.scrollHeight;\n this.onChange?.(this.selected.size);\n\n if(scroll) {\n this.selectedScrollable.scrollIntoViewNew({\n element: this.input,\n position: 'center'\n });\n }\n\n return div;\n }\n\n public remove(key: PeerId | string) {\n if(!this.multiSelect) return;\n // const div = this.selected[peerId];\n const div = this.selectedContainer.querySelector(`[data-key=\"${key}\"]`) as HTMLElement;\n div.classList.remove('scale-in');\n void div.offsetWidth;\n div.classList.add('scale-out');\n\n const onAnimationEnd = () => {\n this.selected.delete(key);\n div.remove();\n this.onChange && this.onChange(this.selected.size);\n };\n\n if(liteMode.isAvailable('animations')) {\n div.addEventListener('animationend', onAnimationEnd, {once: true});\n } else {\n onAnimationEnd();\n }\n }\n\n public getSelected() {\n return [...this.selected];\n }\n\n public addInitial(values: any[]) {\n values.forEach((value) => {\n this.add(value, undefined, false);\n });\n\n window.requestAnimationFrame(() => { // ! not the best place for this raf though it works\n this.selectedScrollable.scrollIntoViewNew({\n element: this.input,\n position: 'center',\n forceDirection: FocusDirection.Static\n });\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../lib/appManagers/appDocsManager';\nimport ProgressivePreloader from './preloader';\nimport appMediaPlaybackController, {MediaItem, MediaSearchContext} from './appMediaPlaybackController';\nimport {DocumentAttribute, Message} from '../layer';\nimport mediaSizes from '../helpers/mediaSizes';\nimport {IS_SAFARI} from '../environment/userAgent';\nimport rootScope from '../lib/rootScope';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport LazyLoadQueue from './lazyLoadQueue';\nimport deferredPromise, {CancellablePromise} from '../helpers/cancellablePromise';\nimport ListenerSetter, {Listener} from '../helpers/listenerSetter';\nimport noop from '../helpers/noop';\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport {joinElementsWith} from '../lib/langPack';\nimport {MiddleEllipsisElement} from './middleEllipsis';\nimport {formatFullSentTime} from '../helpers/date';\nimport throttleWithRaf from '../helpers/schedulers/throttleWithRaf';\nimport {NULL_PEER_ID} from '../lib/mtproto/mtproto_config';\nimport formatBytes from '../helpers/formatBytes';\nimport {animateSingle} from '../helpers/animation';\nimport clamp from '../helpers/number/clamp';\nimport toHHMMSS from '../helpers/string/toHHMMSS';\nimport MediaProgressLine from './mediaProgressLine';\nimport setInnerHTML from '../helpers/dom/setInnerHTML';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport wrapEmojiText from '../lib/richTextProcessor/wrapEmojiText';\nimport wrapSenderToPeer from './wrappers/senderToPeer';\nimport wrapSentTime from './wrappers/sentTime';\nimport getMediaFromMessage from '../lib/appManagers/utils/messages/getMediaFromMessage';\nimport appDownloadManager from '../lib/appManagers/appDownloadManager';\nimport wrapPhoto from './wrappers/photo';\nimport {doubleRaf} from '../helpers/schedulers';\n\nrootScope.addEventListener('messages_media_read', ({mids, peerId}) => {\n mids.forEach((mid) => {\n const attr = `[data-mid=\"${mid}\"][data-peer-id=\"${peerId}\"]`;\n (Array.from(document.querySelectorAll(`audio-element.is-unread${attr}, .media-round.is-unread${attr}`)) as AudioElement[]).forEach((elem) => {\n elem.classList.remove('is-unread');\n });\n });\n});\n\n// https://github.com/LonamiWebs/Telethon/blob/4393ec0b83d511b6a20d8a20334138730f084375/telethon/utils.py#L1285\nexport function decodeWaveform(waveform: Uint8Array | number[]) {\n if(!(waveform instanceof Uint8Array)) {\n waveform = new Uint8Array(waveform);\n }\n\n const bitCount = waveform.length * 8;\n const valueCount = bitCount / 5 | 0;\n if(!valueCount) {\n return new Uint8Array([]);\n }\n\n let result: Uint8Array;\n try {\n const dataView = new DataView(waveform.buffer);\n result = new Uint8Array(valueCount);\n for(let i = 0; i < valueCount; i++) {\n const byteIndex = i * 5 / 8 | 0;\n const bitShift = i * 5 % 8;\n const value = dataView.getUint16(byteIndex, true);\n result[i] = (value >> bitShift) & 0b00011111;\n }\n } catch(err) {\n result = new Uint8Array([]);\n }\n\n return result;\n}\n\nfunction createWaveformBars(waveform: Uint8Array, duration: number) {\n const barWidth = 2;\n const barMargin = 2;\n const barHeightMin = 4;\n const barHeightMax = mediaSizes.isMobile ? 16 : 23;\n\n const minW = mediaSizes.isMobile ? 152 : 190;\n const maxW = mediaSizes.isMobile ? 190 : 256;\n const availW = clamp(duration / 60 * maxW, minW, maxW);\n\n const normValue = Math.max(...waveform);\n const wfSize = waveform.length;\n const barCount = Math.min((availW / (barWidth + barMargin)) | 0, wfSize);\n\n let maxValue = 0;\n const maxDelta = barHeightMax - barHeightMin;\n\n let html = '';\n for(let i = 0, barX = 0, sumI = 0; i < wfSize; ++i) {\n const value = waveform[i] || 0;\n if((sumI + barCount) >= wfSize) { // draw bar\n sumI = sumI + barCount - wfSize;\n if(sumI < (barCount + 1) / 2) {\n if(maxValue < value) maxValue = value;\n }\n\n const bar_value = Math.max(((maxValue * maxDelta) + ((normValue + 1) / 2)) / (normValue + 1), barHeightMin);\n\n const h = `<rect class=\"audio-waveform-bar\" x=\"${barX}\" y=\"${barHeightMax - bar_value}\" width=\"${barWidth}\" height=\"${bar_value}\" rx=\"1\" ry=\"1\"></rect>`;\n html += h;\n\n barX += barWidth + barMargin;\n\n if(sumI < (barCount + 1) / 2) {\n maxValue = 0;\n } else {\n maxValue = value;\n }\n } else {\n if(maxValue < value) maxValue = value;\n\n sumI += barCount;\n }\n }\n\n let container: HTMLElement, svg: SVGSVGElement;\n\n if(!html) {\n\n } else {\n container = document.createElement('div');\n container.classList.add('audio-waveform');\n\n svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.classList.add('audio-waveform-bars');\n svg.setAttributeNS(null, 'width', '' + availW);\n svg.setAttributeNS(null, 'height', '' + barHeightMax);\n svg.setAttributeNS(null, 'viewBox', `0 0 ${availW} ${barHeightMax}`);\n svg.insertAdjacentHTML('beforeend', html);\n\n container.append(svg);\n }\n\n return {svg, container, availW};\n}\n\nasync function wrapVoiceMessage(audioEl: AudioElement) {\n audioEl.classList.add('is-voice');\n\n const message = audioEl.message;\n const doc = getMediaFromMessage(message) as MyDocument;\n\n if(message.pFlags.out) {\n audioEl.classList.add('is-out');\n }\n\n let waveform = (doc.attributes.find((attribute) => attribute._ === 'documentAttributeAudio') as DocumentAttribute.documentAttributeAudio).waveform || new Uint8Array([]);\n waveform = decodeWaveform(waveform.slice(0, 63));\n\n const {svg, container: svgContainer, availW} = createWaveformBars(waveform, doc.duration);\n\n let fakeSvgContainer: HTMLElement;\n if(svgContainer) {\n fakeSvgContainer = svgContainer.cloneNode(true) as HTMLElement;\n fakeSvgContainer.classList.add('audio-waveform-fake');\n svgContainer.classList.add('audio-waveform-background');\n }\n\n const waveformContainer = document.createElement('div');\n waveformContainer.classList.add('audio-waveform-container');\n\n if(svgContainer) {\n waveformContainer.append(svgContainer, fakeSvgContainer);\n }\n\n const timeDiv = document.createElement('div');\n timeDiv.classList.add('audio-time');\n audioEl.append(waveformContainer, timeDiv);\n\n if(audioEl.transcriptionState !== undefined) {\n audioEl.classList.add('can-transcribe');\n const speechRecognitionDiv = document.createElement('div');\n speechRecognitionDiv.classList.add('audio-to-text-button');\n const speechRecognitionIcon = document.createElement('span');\n speechRecognitionIcon.classList.add('tgico-transcribe');\n const speechRecognitionLoader = document.createElement('div');\n speechRecognitionLoader.classList.add('loader');\n speechRecognitionLoader.innerHTML = '<svg class=\"audio-transcribe-outline\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 24\"><rect class=\"audio-transcribe-outline-rect\" fill=\"transparent\" stroke-width=\"3\" stroke-linejoin=\"round\" rx=\"6\" ry=\"6\" stroke=\"var(--message-primary-color)\" stroke-dashoffset=\"1\" stroke-dasharray=\"32,68\" width=\"32\" height=\"24\"></rect></svg>'\n speechRecognitionDiv.append(speechRecognitionIcon);\n\n speechRecognitionDiv.onclick = () => {\n const speechTextDiv = (findUpClassName(audioEl, 'document-wrapper') || findUpClassName(audioEl, 'quote-text')).querySelector<HTMLElement>('.audio-transcribed-text');\n if(audioEl.transcriptionState === 0) {\n if(speechTextDiv) {\n speechTextDiv.classList.remove('hide');\n speechRecognitionIcon.classList.remove('tgico-transcribe');\n speechRecognitionIcon.classList.add('tgico-up');\n // TODO: State to enum\n audioEl.transcriptionState = 2;\n } else {\n const message = audioEl.message;\n if(message.pFlags.is_outgoing) {\n return;\n }\n\n audioEl.transcriptionState = 1;\n !speechRecognitionLoader.parentElement && speechRecognitionDiv.append(speechRecognitionLoader);\n doubleRaf().then(() => {\n if(audioEl.transcriptionState === 1) {\n speechRecognitionLoader.classList.add('active');\n }\n });\n\n audioEl.managers.appMessagesManager.transcribeAudio(message).catch(noop);\n }\n } else if(audioEl.transcriptionState === 2) {\n // Hide transcription\n speechTextDiv.classList.add('hide');\n speechRecognitionIcon.classList.remove('tgico-up');\n speechRecognitionIcon.classList.add('tgico-transcribe');\n audioEl.transcriptionState = 0;\n }\n };\n\n audioEl.append(speechRecognitionDiv);\n }\n\n let progress = svg as any as HTMLElement, progressLine: MediaProgressLine;\n if(!progress) {\n progressLine = new MediaProgressLine();\n\n waveformContainer.append(progressLine.container);\n }\n\n const onLoad = () => {\n let audio = audioEl.audio;\n\n const setAnimation = () => {\n animateSingle(() => {\n if(!audio) return false;\n onTimeUpdate();\n return !audio.paused;\n }, audioEl);\n };\n\n const onTimeUpdate = () => {\n if(fakeSvgContainer) {\n fakeSvgContainer.style.width = (audio.currentTime / audio.duration * 100) + '%';\n }\n };\n\n if(!audio.paused || (audio.currentTime > 0 && audio.currentTime !== audio.duration)) {\n onTimeUpdate();\n }\n\n const throttledTimeUpdate = throttleWithRaf(onTimeUpdate);\n audioEl.addAudioListener('timeupdate', throttledTimeUpdate);\n audioEl.addAudioListener('ended', throttledTimeUpdate);\n audioEl.addAudioListener('play', setAnimation);\n\n progress && audioEl.readyPromise.then(() => {\n let mousedown = false, mousemove = false;\n progress.addEventListener('mouseleave', (e) => {\n if(mousedown) {\n audioEl.togglePlay(undefined, true);\n mousedown = false;\n }\n mousemove = false;\n });\n progress.addEventListener('mousemove', (e) => {\n mousemove = true;\n if(mousedown) scrub(e);\n });\n progress.addEventListener('mousedown', (e) => {\n e.preventDefault();\n if(e.button !== 0) return;\n if(!audio.paused) {\n audioEl.togglePlay(undefined, false);\n }\n\n scrub(e);\n mousedown = true;\n });\n progress.addEventListener('mouseup', (e) => {\n if(mousemove && mousedown) {\n audioEl.togglePlay(undefined, true);\n mousedown = false;\n }\n });\n attachClickEvent(progress, (e) => {\n cancelEvent(e);\n if(!audio.paused) scrub(e);\n });\n\n function scrub(e: MouseEvent | TouchEvent) {\n let offsetX: number;\n if(e instanceof MouseEvent) {\n offsetX = e.offsetX;\n } else { // touch\n const rect = (e.target as HTMLElement).getBoundingClientRect();\n offsetX = e.targetTouches[0].pageX - rect.left;\n }\n\n const scrubTime = offsetX / availW /* width */ * audio.duration;\n audio.currentTime = scrubTime;\n }\n }, noop);\n\n !progress && progressLine.setMedia({\n media: audio,\n streamable: doc.supportsStreaming,\n duration: doc.duration\n });\n\n return () => {\n progress?.remove();\n progress = null;\n audio = null;\n };\n };\n\n return onLoad;\n}\n\nasync function wrapAudio(audioEl: AudioElement) {\n const withTime = audioEl.withTime;\n\n const message = audioEl.message;\n const doc = getMediaFromMessage(message) as MyDocument;\n\n const isVoice = doc.type === 'voice' || doc.type === 'round';\n const descriptionEl = document.createElement('div');\n descriptionEl.classList.add('audio-description');\n\n const audioAttribute = doc.attributes.find((attr) => attr._ === 'documentAttributeAudio') as DocumentAttribute.documentAttributeAudio;\n\n if(!isVoice) {\n const parts: (Node | string)[] = [];\n if(audioAttribute?.performer) {\n parts.push(wrapEmojiText(audioAttribute.performer));\n }\n\n if(withTime) {\n parts.push(formatFullSentTime(message.date));\n } else if(!parts.length) {\n parts.push(formatBytes(doc.size));\n }\n\n if(audioEl.showSender) {\n parts.push(await wrapSenderToPeer(message));\n }\n\n descriptionEl.append(...joinElementsWith(parts, ' • '));\n }\n\n const html = `\n <div class=\"audio-details\">\n <div class=\"audio-title\"></div>\n <div class=\"audio-subtitle\"><div class=\"audio-time\"></div></div>\n </div>`;\n audioEl.insertAdjacentHTML('beforeend', html);\n\n const titleEl = audioEl.querySelector('.audio-title') as HTMLElement;\n\n const middleEllipsisEl = new MiddleEllipsisElement();\n middleEllipsisEl.dataset.fontWeight = audioEl.dataset.fontWeight;\n middleEllipsisEl.dataset.fontSize = audioEl.dataset.fontSize;\n middleEllipsisEl.dataset.sizeType = audioEl.dataset.sizeType;\n (middleEllipsisEl as any).getSize = (audioEl as any).getSize;\n if(isVoice) {\n middleEllipsisEl.append(await wrapSenderToPeer(message));\n } else {\n setInnerHTML(middleEllipsisEl, wrapEmojiText(audioAttribute?.title ?? doc.file_name));\n }\n\n titleEl.append(middleEllipsisEl);\n\n if(audioEl.showSender) {\n titleEl.append(wrapSentTime(message));\n }\n\n const subtitleDiv = audioEl.querySelector('.audio-subtitle') as HTMLDivElement;\n subtitleDiv.append(descriptionEl);\n\n const onLoad = () => {\n let launched = false;\n\n let progressLine = new MediaProgressLine();\n progressLine.setMedia({\n media: audioEl.audio,\n streamable: doc.supportsStreaming,\n duration: doc.duration\n });\n\n audioEl.addAudioListener('ended', () => {\n audioEl.classList.remove('audio-show-progress');\n // Reset subtitle\n subtitleDiv.lastChild.replaceWith(descriptionEl);\n launched = false;\n });\n\n const onPlay = () => {\n if(!launched) {\n audioEl.classList.add('audio-show-progress');\n launched = true;\n\n if(progressLine) {\n subtitleDiv.lastChild.replaceWith(progressLine.container);\n }\n }\n };\n\n audioEl.addAudioListener('play', onPlay);\n\n if(!audioEl.audio.paused || audioEl.audio.currentTime > 0) {\n onPlay();\n }\n\n return () => {\n progressLine.removeListeners();\n progressLine.container.remove();\n progressLine = null;\n };\n };\n\n return onLoad;\n}\n\nfunction constructDownloadPreloader(tryAgainOnFail = true) {\n const preloader = new ProgressivePreloader({cancelable: true, tryAgainOnFail});\n preloader.construct();\n\n if(!tryAgainOnFail) {\n preloader.circle.setAttributeNS(null, 'r', '23');\n preloader.totalLength = 143.58203125;\n }\n\n return preloader;\n}\n\nexport const findMediaTargets = (anchor: HTMLElement, anchorMid: number/* , useSearch: boolean */) => {\n let prev: MediaItem[], next: MediaItem[];\n // if(anchor.classList.contains('search-super-item') || !useSearch) {\n const isBubbles = !anchor.classList.contains('search-super-item');\n const container = findUpClassName(anchor, !isBubbles ? 'tabs-tab' : 'bubbles-inner');\n if(container) {\n const attr = `:not([data-is-outgoing=\"1\"])`;\n const justAudioSelector = `.audio:not(.is-voice)${attr}`;\n let selectors: string[];\n if(!anchor.matches(justAudioSelector)) {\n selectors = [`.audio.is-voice${attr}`, `.media-round${attr}`];\n } else {\n selectors = [justAudioSelector];\n }\n\n if(isBubbles) {\n const prefix = '.bubble:not(.webpage) ';\n selectors = selectors.map((s) => prefix + s);\n }\n\n const selector = selectors.join(', ');\n\n const elements = Array.from(container.querySelectorAll(selector)) as HTMLElement[];\n const idx = elements.indexOf(anchor);\n\n const mediaItems: MediaItem[] = elements.map((element) => ({peerId: element.dataset.peerId.toPeerId(), mid: +element.dataset.mid}));\n\n prev = mediaItems.slice(0, idx);\n next = mediaItems.slice(idx + 1);\n }\n // }\n\n if((next.length && next[0].mid < anchorMid) || (prev.length && prev[prev.length - 1].mid > anchorMid)) {\n [prev, next] = [next.reverse(), prev.reverse()];\n }\n\n // prev = next = undefined;\n\n return [prev, next];\n};\n\nexport default class AudioElement extends HTMLElement {\n public audio: HTMLAudioElement;\n public preloader: ProgressivePreloader;\n public message: Message.message;\n public withTime = false;\n public voiceAsMusic = false;\n public searchContext: MediaSearchContext;\n public showSender = false;\n public noAutoDownload: boolean;\n public lazyLoadQueue: LazyLoadQueue;\n public loadPromises: Promise<any>[];\n public managers: AppManagers;\n public transcriptionState: number;\n\n private listenerSetter = new ListenerSetter();\n private onTypeDisconnect: () => void;\n public onLoad: (autoload?: boolean) => void;\n public readyPromise: CancellablePromise<void>;\n public load: (shouldPlay: boolean, controlledAutoplay?: boolean) => void;\n\n public async render() {\n this.classList.add('audio');\n this.managers = rootScope.managers;\n\n this.dataset.mid = '' + this.message.mid;\n this.dataset.peerId = '' + this.message.peerId;\n\n const doc = getMediaFromMessage(this.message) as MyDocument;\n const isRealVoice = doc.type === 'voice';\n const isVoice = !this.voiceAsMusic && isRealVoice;\n const isOutgoing = this.message.pFlags.is_outgoing;\n const uploadingFileName = this.message?.uploadingFileName;\n\n const getDurationStr = () => {\n const duration = this.audio && this.audio.readyState >= this.audio.HAVE_CURRENT_DATA ? this.audio.duration : doc.duration;\n return toHHMMSS(duration | 0);\n };\n\n this.innerHTML = `\n <div class=\"audio-toggle audio-ico\">\n <div class=\"audio-play-icon\">\n <div class=\"part one\" x=\"0\" y=\"0\" fill=\"#fff\"></div>\n <div class=\"part two\" x=\"0\" y=\"0\" fill=\"#fff\"></div>\n </div>\n </div>`;\n\n const toggle = this.firstElementChild as HTMLElement;\n\n const downloadDiv = document.createElement('div');\n downloadDiv.classList.add('audio-download');\n\n const isUnread = doc.type !== 'audio' && this.message && this.message.pFlags.media_unread;\n if(isUnread) {\n this.classList.add('is-unread');\n }\n\n if(uploadingFileName) {\n this.classList.add('is-outgoing');\n this.append(downloadDiv);\n }\n\n const onTypeLoad = await (isVoice ? wrapVoiceMessage(this) : wrapAudio(this));\n\n const audioTimeDiv = this.querySelector('.audio-time') as HTMLDivElement;\n audioTimeDiv.textContent = getDurationStr();\n\n const onLoad = this.onLoad = (autoload: boolean) => {\n this.onLoad = undefined;\n\n const audio = this.audio = appMediaPlaybackController.addMedia(this.message, autoload);\n\n const readyPromise = this.readyPromise = deferredPromise<void>();\n if(this.audio.readyState >= this.audio.HAVE_CURRENT_DATA) readyPromise.resolve();\n else {\n this.addAudioListener('canplay', () => readyPromise.resolve(), {once: true});\n }\n\n this.onTypeDisconnect = onTypeLoad();\n\n const getTimeStr = () => toHHMMSS(audio.currentTime | 0) + (isVoice ? (' / ' + getDurationStr()) : '');\n\n const onPlay = () => {\n audioTimeDiv.innerText = getTimeStr();\n toggle.classList.toggle('playing', !audio.paused);\n };\n\n if(!audio.paused || (audio.currentTime > 0 && audio.currentTime !== audio.duration)) {\n onPlay();\n }\n\n attachClickEvent(toggle, (e) => this.togglePlay(e), {listenerSetter: this.listenerSetter});\n\n this.addAudioListener('ended', () => {\n toggle.classList.remove('playing');\n audioTimeDiv.innerText = getDurationStr();\n });\n\n this.addAudioListener('timeupdate', () => {\n if((!audio.currentTime && audio.paused) || appMediaPlaybackController.isSafariBuffering(audio)) return;\n audioTimeDiv.innerText = getTimeStr();\n });\n\n this.addAudioListener('pause', () => {\n toggle.classList.remove('playing');\n });\n\n this.addAudioListener('play', onPlay);\n };\n\n if(doc.thumbs?.length) {\n const imgs: HTMLElement[] = [];\n const wrapped = await wrapPhoto({\n photo: doc,\n message: null,\n container: toggle,\n boxWidth: 48,\n boxHeight: 48,\n loadPromises: this.loadPromises,\n withoutPreloader: true,\n lazyLoadQueue: this.lazyLoadQueue\n });\n toggle.style.width = toggle.style.height = '';\n if(wrapped.images.thumb) imgs.push(wrapped.images.thumb);\n if(wrapped.images.full) imgs.push(wrapped.images.full);\n\n this.classList.add('audio-with-thumb');\n imgs.forEach((img) => img.classList.add('audio-thumb'));\n }\n\n if(!isOutgoing) {\n let preloader: ProgressivePreloader = this.preloader;\n\n const autoDownload = doc.type !== 'audio'/* || !this.noAutoDownload */;\n onLoad(autoDownload);\n\n const r = this.load = (shouldPlay: boolean, controlledAutoplay?: boolean) => {\n this.load = undefined;\n\n if(this.audio.src) {\n return;\n }\n\n appMediaPlaybackController.resolveWaitingForLoadMedia(this.message.peerId, this.message.mid, this.message.pFlags.is_scheduled);\n\n this.onDownloadInit(shouldPlay);\n\n if(!preloader) {\n if(doc.supportsStreaming) {\n this.classList.add('corner-download');\n\n let pauseListener: Listener;\n const onPlay = () => {\n const preloader = constructDownloadPreloader(false);\n const deferred = deferredPromise<void>();\n deferred.notifyAll({done: 75, total: 100});\n deferred.catch(() => {\n this.audio.pause();\n appMediaPlaybackController.willBePlayed(undefined);\n });\n deferred.cancel = () => {\n deferred.cancel = noop;\n const err = new Error();\n (err as any).type = 'CANCELED';\n deferred.reject(err);\n };\n preloader.attach(downloadDiv, false, deferred);\n\n pauseListener = this.addAudioListener('pause', () => {\n deferred.cancel();\n }, {once: true}) as any;\n\n this.onDownloadInit(shouldPlay);\n };\n\n /* if(!this.audio.paused) {\n onPlay();\n } */\n\n const playListener: any = this.addAudioListener('play', onPlay);\n this.readyPromise.then(() => {\n this.listenerSetter.remove(playListener);\n pauseListener && this.listenerSetter.remove(pauseListener);\n });\n } else {\n preloader = constructDownloadPreloader();\n\n if(!shouldPlay) {\n this.readyPromise = deferredPromise();\n }\n\n const load = () => {\n this.onDownloadInit(shouldPlay);\n\n const download = appDownloadManager.downloadMediaURL({media: doc});\n\n if(!shouldPlay) {\n download.then(() => {\n this.readyPromise.resolve();\n });\n }\n\n preloader.attach(downloadDiv, false, download);\n return {download};\n };\n\n preloader.setDownloadFunction(load);\n load();\n }\n }\n\n if(this.classList.contains('corner-download')) {\n toggle.append(downloadDiv);\n } else {\n this.append(downloadDiv);\n }\n\n this.classList.add('downloading');\n\n this.readyPromise.then(() => {\n this.classList.remove('downloading');\n downloadDiv.classList.add('downloaded');\n setTimeout(() => {\n downloadDiv.remove();\n }, 200);\n\n // setTimeout(() => {\n // release loaded audio\n if(!controlledAutoplay && appMediaPlaybackController.willBePlayedMedia === this.audio) {\n this.audio.play();\n appMediaPlaybackController.willBePlayed(undefined);\n }\n // }, 10e3);\n });\n };\n\n if(!this.audio?.src) {\n if(autoDownload) {\n r(false);\n } else {\n attachClickEvent(toggle, () => {\n r(true);\n }, {once: true, capture: true, passive: false, listenerSetter: this.listenerSetter});\n }\n }\n } else if(uploadingFileName) {\n this.preloader = constructDownloadPreloader(false);\n this.preloader.attachPromise(appDownloadManager.getUpload(uploadingFileName));\n this.dataset.isOutgoing = '1';\n this.preloader.attach(downloadDiv, false);\n // onLoad();\n }\n }\n\n private onDownloadInit(shouldPlay: boolean) {\n if(shouldPlay) {\n appMediaPlaybackController.willBePlayed(this.audio); // prepare for loading audio\n\n if(IS_SAFARI && !this.audio.autoplay) {\n this.audio.autoplay = true;\n }\n }\n }\n\n public togglePlay(e?: Event, paused = this.audio.paused) {\n e && cancelEvent(e);\n\n if(paused) {\n this.setTargetsIfNeeded();\n this.audio.play().catch(() => {});\n } else {\n this.audio.pause();\n }\n }\n\n public setTargetsIfNeeded() {\n const hadSearchContext = !!this.searchContext;\n if(appMediaPlaybackController.setSearchContext(this.searchContext || {\n peerId: NULL_PEER_ID,\n inputFilter: {_: 'inputMessagesFilterEmpty'},\n useSearch: false\n })) {\n const [prev, next] = !hadSearchContext ? [] : findMediaTargets(this, this.message.mid/* , this.searchContext.useSearch */);\n appMediaPlaybackController.setTargets({peerId: this.message.peerId, mid: this.message.mid}, prev, next);\n }\n }\n\n public playWithTimestamp(timestamp: number) {\n this.load?.(true);\n this.audio.currentTime = timestamp;\n this.togglePlay(undefined, true);\n // appMediaPlaybackController.willBePlayed(this.audio); // prepare for loading audio\n // this.readyPromise.then(() => {\n // if(appMediaPlaybackController.willBePlayedMedia !== this.audio && this.audio.paused) {\n // return;\n // }\n\n // appMediaPlaybackController.willBePlayed(undefined);\n\n // this.audio.currentTime = timestamp;\n // this.togglePlay(undefined, true);\n // });\n }\n\n get addAudioListener() {\n return this.listenerSetter.add(this.audio);\n }\n\n disconnectedCallback() {\n setTimeout(() => {\n if(this.isConnected) {\n return;\n }\n\n if(this.onTypeDisconnect) {\n this.onTypeDisconnect();\n this.onTypeDisconnect = null;\n }\n\n if(this.readyPromise) {\n this.readyPromise.reject();\n }\n\n if(this.listenerSetter) {\n this.listenerSetter.removeAll();\n this.listenerSetter = null;\n }\n\n if(this.preloader) {\n this.preloader = null;\n }\n }, 100);\n }\n}\n\ncustomElements.define('audio-element', AudioElement);\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {Photo} from '../layer';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport ListLoader, {ListLoaderOptions} from './listLoader';\n\nexport default class AvatarListLoader<Item extends {photoId: Photo.photo['id']}> extends ListLoader<Item, any> {\n private peerId: PeerId;\n private managers: AppManagers;\n\n constructor(options: Omit<ListLoaderOptions<Item, any>, 'loadMore'> & {peerId: PeerId, managers: AppManagers}) {\n super({\n ...options,\n loadMore: (anchor, older, loadCount) => {\n if(this.peerId.isAnyChat() || !older) return Promise.resolve({count: 0, items: []}); // ! это значит, что открыло аватар чата, но следующих фотографий нет.\n\n const maxId = anchor?.photoId;\n return this.managers.appPhotosManager.getUserPhotos(this.peerId, maxId, loadCount).then((value) => {\n const items = value.photos.map((photoId) => {\n return {element: null as HTMLElement, photoId} as any;\n });\n\n return {count: value.count, items};\n });\n }\n });\n\n this.loadedAllUp = true;\n this.peerId = options.peerId;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport AvatarListLoader from '../helpers/avatarListLoader';\nimport {Photo} from '../layer';\nimport appDownloadManager from '../lib/appManagers/appDownloadManager';\nimport appImManager from '../lib/appManagers/appImManager';\nimport rootScope from '../lib/rootScope';\nimport AppMediaViewerBase from './appMediaViewerBase';\n\ntype AppMediaViewerAvatarTargetType = {element: HTMLElement, photoId: Photo.photo['id'], photo?: Photo.photo};\nexport default class AppMediaViewerAvatar extends AppMediaViewerBase<'', 'delete', AppMediaViewerAvatarTargetType> {\n public peerId: PeerId;\n\n constructor(peerId: PeerId) {\n super(new AvatarListLoader({peerId, managers: rootScope.managers}), [/* 'delete' */]);\n\n this.peerId = peerId;\n\n this.setBtnMenuToggle([{\n icon: 'download',\n text: 'MediaViewer.Context.Download',\n onClick: this.onDownloadClick\n }/* , {\n icon: 'delete danger btn-disabled',\n text: 'Delete',\n onClick: () => {}\n } */]);\n\n // * constructing html end\n\n this.setListeners();\n }\n\n onPrevClick = (target: AppMediaViewerAvatarTargetType) => {\n this.openMedia({\n photoId: target.photoId,\n target: target.element,\n fromRight: -1\n });\n };\n\n onNextClick = (target: AppMediaViewerAvatarTargetType) => {\n this.openMedia({\n photoId: target.photoId,\n target: target.element,\n fromRight: 1\n });\n };\n\n onDownloadClick = () => {\n appDownloadManager.downloadToDisc({\n media: this.target.photo,\n queueId: appImManager.chat.bubbles.lazyLoadQueue.queueId\n });\n };\n\n public async openMedia({\n photoId,\n target,\n fromRight = 0,\n prevTargets,\n nextTargets\n }: {\n photoId: Photo.photo['id'],\n target?: HTMLElement,\n fromRight?: number,\n prevTargets?: AppMediaViewerAvatarTargetType[],\n nextTargets?: AppMediaViewerAvatarTargetType[]\n }) {\n if(this.setMoverPromise) return this.setMoverPromise;\n\n const photo = await this.managers.appPhotosManager.getPhoto(photoId);\n const ret = super._openMedia({\n media: photo,\n timestamp: photo.date,\n fromId: this.peerId,\n fromRight,\n target,\n reverse: false,\n prevTargets,\n nextTargets\n });\n this.target.photoId = photo.id;\n this.target.photo = photo;\n\n return ret;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport rootScope from '../lib/rootScope';\nimport {Message, Photo} from '../layer';\nimport type LazyLoadQueue from './lazyLoadQueue';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport AppMediaViewer from './appMediaViewer';\nimport AppMediaViewerAvatar from './appMediaViewerAvatar';\nimport isObject from '../helpers/object/isObject';\nimport {ArgumentTypes} from '../types';\nimport putPhoto from './putPhoto';\nimport {recordPromise} from '../helpers/recordPromise';\nimport {getMiddleware, MiddlewareHelper} from '../helpers/middleware';\n\nconst onAvatarUpdate = ({peerId, threadId}: {peerId: PeerId, threadId?: number}) => {\n let query = 'avatar-element[data-peer-id=\"' + peerId + '\"]';\n if(threadId) {\n query += '[data-thread-id=\"' + threadId + '\"]';\n }\n\n (Array.from(document.querySelectorAll(query)) as AvatarElement[]).forEach((elem) => {\n // console.log('updating avatar:', elem);\n elem.update();\n });\n};\n\nrootScope.addEventListener('avatar_update', onAvatarUpdate);\nrootScope.addEventListener('peer_title_edit', async(data) => {\n if(!(await rootScope.managers.appAvatarsManager.isAvatarCached(data.peerId))) {\n onAvatarUpdate(data);\n }\n});\n\nexport async function openAvatarViewer(\n target: HTMLElement,\n peerId: PeerId,\n middleware: () => boolean,\n message?: any,\n prevTargets?: {element: HTMLElement, item: Photo.photo['id'] | Message.messageService}[],\n nextTargets?: typeof prevTargets\n) {\n let photo = await rootScope.managers.appProfileManager.getFullPhoto(peerId);\n if(!middleware() || !photo) {\n return;\n }\n\n const getTarget = () => {\n const good = Array.from(target.querySelectorAll('img')).find((img) => !img.classList.contains('emoji'));\n return good ? target : null;\n };\n\n if(peerId.isAnyChat()) {\n const hadMessage = !!message;\n const inputFilter = 'inputMessagesFilterChatPhotos';\n if(!message) {\n message = await rootScope.managers.appMessagesManager.getSearch({\n peerId,\n inputFilter: {_: inputFilter},\n maxId: 0,\n limit: 1\n }).then((value) => {\n // console.log(lol);\n // ! by descend\n return value.history[0];\n });\n\n if(!middleware()) {\n return;\n }\n }\n\n if(message) {\n // ! гений в деле, костылируем (но это гениально)\n const messagePhoto = message.action.photo;\n if(messagePhoto.id !== photo.id) {\n if(!hadMessage) {\n message = rootScope.managers.appMessagesManager.generateFakeAvatarMessage(peerId, photo);\n } else {\n\n }\n }\n\n const f = (arr: typeof prevTargets) => arr.map((el) => ({\n element: el.element,\n mid: (el.item as Message.messageService).mid,\n peerId: (el.item as Message.messageService).peerId\n }));\n\n new AppMediaViewer()\n .setSearchContext({\n peerId,\n inputFilter: {_: inputFilter}\n })\n .openMedia({\n message,\n target: getTarget(),\n prevTargets: prevTargets ? f(prevTargets) : undefined,\n nextTargets: nextTargets ? f(nextTargets) : undefined\n });\n\n return;\n }\n }\n\n if(photo) {\n if(!isObject(message) && message) {\n photo = await rootScope.managers.appPhotosManager.getPhoto(message);\n }\n\n const f = (arr: typeof prevTargets) => arr.map((el) => ({\n element: el.element,\n photoId: el.item as string\n }));\n\n new AppMediaViewerAvatar(peerId).openMedia({\n photoId: photo.id,\n target: getTarget(),\n prevTargets: prevTargets ? f(prevTargets) : undefined,\n nextTargets: nextTargets ? f(nextTargets) : undefined\n });\n }\n}\n\nconst believeMe: Map<string, Set<AvatarElement>> = new Map();\nconst seen: Set<PeerId> = new Set();\n\nfunction getAvatarQueueKey(peerId: PeerId, threadId?: number) {\n return peerId + (threadId ? '_' + threadId : '');\n}\n\nexport default class AvatarElement extends HTMLElement {\n public peerId: PeerId;\n public isDialog: boolean;\n public peerTitle: string;\n public loadPromises: Promise<any>[];\n public lazyLoadQueue: LazyLoadQueue;\n public isBig: boolean;\n public threadId: number;\n private addedToQueue = false;\n public wrapOptions: WrapSomethingOptions;\n\n public middlewareHelper: MiddlewareHelper;\n\n constructor() {\n super();\n this.classList.add('avatar-like');\n this.middlewareHelper = getMiddleware();\n }\n\n disconnectedCallback() {\n // браузер вызывает этот метод при удалении элемента из документа\n // (может вызываться много раз, если элемент многократно добавляется/удаляется)\n const key = getAvatarQueueKey(this.peerId, this.threadId);\n const set = believeMe.get(key);\n if(set?.has(this)) {\n set.delete(this);\n if(!set.size) {\n believeMe.delete(key);\n }\n }\n\n this.lazyLoadQueue?.delete({div: this});\n }\n\n public attachClickEvent() {\n let loading = false;\n attachClickEvent(this, async(e) => {\n cancelEvent(e);\n if(loading) return;\n const peerId = this.peerId;\n loading = true;\n await openAvatarViewer(this, this.peerId, () => this.peerId === peerId);\n loading = false;\n });\n }\n\n public updateOptions(options: Partial<ArgumentTypes<AvatarElement['updateWithOptions']>[0]>) {\n for(const i in options) {\n // @ts-ignore\n this[i] = options[i];\n }\n }\n\n public updateWithOptions(options: {\n peerId: PeerId,\n threadId?: number,\n isDialog?: boolean,\n isBig?: boolean,\n peerTitle?: string,\n lazyLoadQueue?: LazyLoadQueue | false,\n loadPromises?: Promise<any>[],\n wrapOptions?: WrapSomethingOptions\n }) {\n const wasPeerId = this.peerId;\n const wasThreadId = this.threadId;\n this.updateOptions(options);\n const newPeerId = this.peerId;\n const threadId = this.threadId;\n\n if(wasPeerId === newPeerId && wasThreadId === threadId) {\n return;\n }\n\n this.dataset.peerId = '' + newPeerId;\n\n if(threadId) {\n this.dataset.threadId = '' + threadId;\n } else if(wasThreadId) {\n delete this.dataset.threadId;\n }\n\n if(wasPeerId) {\n const key = getAvatarQueueKey(wasPeerId, wasThreadId);\n const set = believeMe.get(key);\n if(set) {\n set.delete(this);\n if(!set.size) {\n believeMe.delete(key);\n }\n }\n }\n\n const middleware = options.wrapOptions?.middleware;\n this.middlewareHelper.destroy();\n if(middleware) {\n this.middlewareHelper = middleware.create();\n } else {\n this.middlewareHelper.destroy();\n }\n\n return this.update();\n }\n\n public remove() {\n this.middlewareHelper.destroy();\n super.remove();\n }\n\n private r(onlyThumb = false) {\n const promise = putPhoto({\n div: this,\n peerId: this.peerId,\n isDialog: this.isDialog,\n title: this.peerTitle,\n onlyThumb,\n isBig: this.isBig,\n threadId: this.threadId,\n wrapOptions: {\n middleware: this.middlewareHelper.get(),\n ...(this.wrapOptions || {})\n }\n });\n // recordPromise(promise, 'avatar putPhoto-' + this.peerId);\n\n if(this.loadPromises) {\n this.loadPromises.push(promise);\n\n promise.finally(() => {\n this.loadPromises = undefined;\n });\n }\n\n return promise;\n }\n\n public update() {\n if(this.lazyLoadQueue) {\n if(!seen.has(this.peerId)) {\n if(this.addedToQueue) return;\n this.addedToQueue = true;\n\n const key = getAvatarQueueKey(this.peerId, this.threadId);\n let set = believeMe.get(key);\n if(!set) {\n believeMe.set(key, set = new Set());\n }\n\n set.add(this);\n\n this.lazyLoadQueue.push({\n div: this,\n load: () => {\n seen.add(this.peerId);\n return this.update();\n }\n });\n\n return this.r(true);\n } else if(this.addedToQueue) {\n this.lazyLoadQueue.delete({div: this});\n }\n }\n\n seen.add(this.peerId);\n\n const promise = this.r();\n\n if(this.addedToQueue) {\n promise.finally(() => {\n this.addedToQueue = false;\n });\n }\n\n const key = getAvatarQueueKey(this.peerId, this.threadId);\n const set = believeMe.get(key);\n if(set) {\n set.delete(this);\n const arr = Array.from(set);\n believeMe.delete(key);\n\n for(let i = 0, length = arr.length; i < length; ++i) {\n arr[i].update();\n }\n }\n\n return promise;\n }\n}\n\ncustomElements.define('avatar-element', AvatarElement);\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {CancellablePromise} from '../helpers/cancellablePromise';\nimport type {InputFile} from '../layer';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport PopupElement from './popups';\nimport PopupAvatar from './popups/avatar';\n\nexport default class AvatarEdit {\n public container: HTMLElement;\n private canvas: HTMLCanvasElement;\n private icon: HTMLSpanElement;\n\n constructor(onChange: (uploadAvatar: () => CancellablePromise<InputFile>) => void, options?: ConstructorParameters<typeof PopupAvatar>[0]) {\n this.container = document.createElement('div');\n this.container.classList.add('avatar-edit');\n\n this.canvas = document.createElement('canvas');\n this.canvas.classList.add('avatar-edit-canvas');\n\n this.icon = document.createElement('span');\n this.icon.classList.add('tgico', 'tgico-cameraadd');\n\n this.container.append(this.canvas, this.icon);\n\n attachClickEvent(this.container, () => {\n PopupElement.createPopup(PopupAvatar, options).open(this.canvas, onChange);\n });\n }\n\n public clear() {\n const ctx = this.canvas.getContext('2d');\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {FormatterArguments, i18n, LangPackKey} from '../lib/langPack';\nimport ripple from './ripple';\n\nexport type ButtonOptions = Partial<{\n noRipple: true,\n onlyMobile: true,\n icon: string,\n rippleSquare: true,\n text: LangPackKey,\n textArgs?: FormatterArguments,\n disabled: boolean,\n asDiv: boolean,\n asLink: boolean\n}>;\n\nexport default function Button<T extends ButtonOptions>(className: string, options: T = {} as T): T['asLink'] extends true ? HTMLAnchorElement : HTMLButtonElement {\n const button = document.createElement(options.asLink ? 'a' : (options.asDiv ? 'div' : 'button'));\n button.className = className + (options.icon ? ' tgico-' + options.icon : '');\n\n if(!options.noRipple) {\n if(options.rippleSquare) {\n button.classList.add('rp-square');\n }\n\n ripple(button);\n }\n\n if(options.onlyMobile) {\n button.classList.add('only-handhelds');\n }\n\n if(options.disabled) {\n button.setAttribute('disabled', 'true');\n }\n\n if(options.text) {\n button.append(i18n(options.text, options.textArgs));\n }\n\n return button as any;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport Button from './button';\n\nconst ButtonCorner = (options: Partial<{className: string, icon: string, noRipple: true, onlyMobile: true, asDiv: boolean}> = {}) => {\n const button = Button('btn-circle btn-corner z-depth-1' + (options.className ? ' ' + options.className : ''), options);\n button.tabIndex = -1;\n return button;\n};\n\nexport default ButtonCorner;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport Button from './button';\n\nconst ButtonIcon = (className?: string, options: Partial<{noRipple: true, onlyMobile: true, asDiv: boolean}> = {}) => {\n const button = Button('btn-icon', {\n icon: className || undefined,\n ...options\n });\n\n return button;\n};\n\nexport default ButtonIcon;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport flatten from '../helpers/array/flatten';\nimport contextMenuController from '../helpers/contextMenuController';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {AttachClickOptions, attachClickEvent} from '../helpers/dom/clickEvent';\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport setInnerHTML from '../helpers/dom/setInnerHTML';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport {FormatterArguments, i18n, LangPackKey} from '../lib/langPack';\nimport CheckboxField from './checkboxField';\nimport {Document} from '../layer';\nimport wrapPhoto from './wrappers/photo';\nimport textToSvgURL from '../helpers/textToSvgURL';\nimport customProperties from '../helpers/dom/customProperties';\nimport {IS_MOBILE} from '../environment/userAgent';\nimport ripple from './ripple';\n\nexport type ButtonMenuItemOptions = {\n icon?: string,\n iconDoc?: Document.document,\n text?: LangPackKey,\n textArgs?: FormatterArguments,\n regularText?: Parameters<typeof setInnerHTML>[1],\n onClick: (e: MouseEvent | TouchEvent) => any,\n checkForClose?: () => boolean,\n element?: HTMLElement,\n textElement?: HTMLElement,\n options?: AttachClickOptions,\n checkboxField?: CheckboxField,\n noCheckboxClickListener?: boolean,\n keepOpen?: boolean,\n separator?: boolean | HTMLElement,\n multiline?: boolean,\n loadPromise?: Promise<any>,\n waitForAnimation?: boolean\n /* , cancelEvent?: true */\n};\n\nexport type ButtonMenuItemOptionsVerifiable = ButtonMenuItemOptions & {\n verify?: () => boolean | Promise<boolean>\n};\n\nfunction ButtonMenuItem(options: ButtonMenuItemOptions) {\n if(options.element) return [options.separator as HTMLElement, options.element].filter(Boolean);\n\n const {icon, iconDoc, text, onClick, checkboxField, noCheckboxClickListener} = options;\n const el = document.createElement('div');\n el.className = 'btn-menu-item rp-overflow' + (icon ? ' tgico-' + icon : '');\n\n if(IS_MOBILE) {\n ripple(el);\n }\n\n let textElement = options.textElement;\n if(!textElement) {\n textElement = options.textElement = text ? i18n(text, options.textArgs) : document.createElement('span');\n if(options.regularText) {\n setInnerHTML(textElement, options.regularText);\n }\n }\n\n if(iconDoc) {\n const iconElement = document.createElement('span');\n iconElement.classList.add('btn-menu-item-icon');\n el.append(iconElement);\n\n options.loadPromise = wrapPhoto({\n container: iconElement,\n photo: iconDoc,\n boxWidth: 24,\n boxHeight: 24,\n withoutPreloader: true,\n noFadeIn: true,\n noBlur: true,\n processUrl: (url) => {\n return fetch(url)\n .then((response) => response.text())\n .then((text) => {\n const color = customProperties.getProperty('primary-text-color');\n const doc = new DOMParser().parseFromString(text, 'image/svg+xml');\n const svg = doc.firstElementChild as HTMLElement;\n svg.querySelectorAll('path').forEach((path) => {\n path.setAttributeNS(null, 'fill', color);\n path.style.stroke = color;\n path.style.strokeWidth = '.25px';\n });\n return textToSvgURL(svg.outerHTML);\n });\n }\n }).then((ret) => ret.loadPromises.thumb);\n }\n\n textElement.classList.add('btn-menu-item-text');\n el.append(textElement);\n\n const keepOpen = !!checkboxField || !!options.keepOpen;\n\n // * cancel mobile keyboard close\n onClick && attachClickEvent(el, /* CLICK_EVENT_NAME !== 'click' || keepOpen ? */ /* async */(e) => {\n cancelEvent(e);\n\n const menu = findUpClassName(e.target, 'btn-menu');\n if(menu && !menu.classList.contains('active')) {\n return;\n }\n\n // let closed = false;\n // if(!keepOpen && !options.checkForClose) {\n // closed = true;\n // contextMenuController.close();\n // }\n\n // wait for closing animation\n // if(options.waitForAnimation && rootScope.settings.animationsEnabled && !options.checkForClose) {\n // await pause(125);\n // }\n\n onClick(e);\n if(options.checkForClose?.() === false) {\n return;\n }\n\n if(!keepOpen/* && !closed */) {\n contextMenuController.close();\n }\n\n if(checkboxField && !noCheckboxClickListener/* && result !== false */) {\n checkboxField.checked = checkboxField.input.type === 'radio' ? true : !checkboxField.checked;\n }\n }/* : onClick */, options.options);\n\n if(checkboxField) {\n el.append(checkboxField.label);\n }\n\n if(options.separator === true) {\n options.separator = document.createElement('hr');\n }\n\n if(options.multiline) {\n el.classList.add('is-multiline');\n }\n\n return [options.separator as HTMLElement, options.element = el].filter(Boolean);\n}\n\nexport function ButtonMenuSync({listenerSetter, buttons}: {\n buttons: ButtonMenuItemOptions[],\n listenerSetter?: ListenerSetter\n}) {\n const el: HTMLElement = document.createElement('div');\n el.classList.add('btn-menu');\n\n if(listenerSetter) {\n buttons.forEach((b) => {\n if(b.options) {\n b.options.listenerSetter = listenerSetter;\n } else {\n b.options = {listenerSetter};\n }\n });\n }\n\n const items = buttons.map(ButtonMenuItem);\n el.append(...flatten(items));\n\n return el;\n}\n\nexport default async function ButtonMenu(options: Parameters<typeof ButtonMenuSync>[0]) {\n const el = ButtonMenuSync(options);\n await Promise.all(options.buttons.map(({loadPromise}) => loadPromise));\n return el;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport contextMenuController from '../helpers/contextMenuController';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {AttachClickOptions, CLICK_EVENT_NAME, hasMouseMovedSinceDown} from '../helpers/dom/clickEvent';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport ButtonIcon from './buttonIcon';\nimport ButtonMenu, {ButtonMenuItemOptionsVerifiable} from './buttonMenu';\nimport filterAsync from '../helpers/array/filterAsync';\nimport {doubleRaf} from '../helpers/schedulers';\n\n// TODO: refactor for attachClickEvent, because if move finger after touchstart, it will start anyway\nexport function ButtonMenuToggleHandler({\n el,\n onOpen,\n options,\n onClose\n}: {\n el: HTMLElement,\n onOpen?: (e: Event) => any,\n options?: AttachClickOptions,\n onClose?: () => void\n}) {\n const add = options?.listenerSetter ? options.listenerSetter.add(el) : el.addEventListener.bind(el);\n\n add(CLICK_EVENT_NAME, (e: Event) => {\n if(!el.classList.contains('btn-menu-toggle') || hasMouseMovedSinceDown(e)) return false;\n\n cancelEvent(e);\n\n if(el.classList.contains('menu-open')) {\n contextMenuController.close();\n } else {\n const result = onOpen?.(e);\n const open = () => {\n const openedMenu = el.querySelector('.btn-menu') as HTMLDivElement;\n contextMenuController.openBtnMenu(openedMenu, onClose);\n };\n\n if(result instanceof Promise) {\n result.then(open);\n } else {\n open();\n }\n }\n });\n}\n\nexport default function ButtonMenuToggle({\n buttonOptions,\n listenerSetter: attachListenerSetter,\n container,\n direction,\n buttons,\n onOpenBefore,\n onOpen,\n onClose,\n onCloseAfter\n}: {\n buttonOptions?: Parameters<typeof ButtonIcon>[1],\n listenerSetter?: ListenerSetter,\n container?: HTMLElement\n direction: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right',\n buttons: ButtonMenuItemOptionsVerifiable[],\n onOpenBefore?: (e: Event) => any,\n onOpen?: (e: Event, element: HTMLElement) => any,\n onClose?: () => void,\n onCloseAfter?: () => void\n}) {\n if(buttonOptions) {\n buttonOptions.asDiv = true;\n }\n\n const button = container ?? ButtonIcon('more', buttonOptions);\n button.classList.add('btn-menu-toggle');\n\n const listenerSetter = new ListenerSetter();\n\n let element: HTMLElement, closeTimeout: number;\n ButtonMenuToggleHandler({\n el: button,\n onOpen: async(e) => {\n await onOpenBefore?.(e);\n if(closeTimeout) {\n clearTimeout(closeTimeout);\n closeTimeout = undefined;\n return;\n }\n\n const f = (b: (typeof buttons[0])[]) => filterAsync(b, (button) => button?.verify?.() ?? true);\n\n const filteredButtons = await f(buttons);\n if(!filteredButtons.length) {\n return;\n }\n\n const _element = element = await ButtonMenu({\n buttons: filteredButtons,\n listenerSetter\n });\n _element.classList.add(direction);\n\n await onOpen?.(e, _element);\n\n button.append(_element);\n await doubleRaf();\n },\n options: {\n listenerSetter: attachListenerSetter\n },\n onClose: () => {\n onClose?.();\n\n closeTimeout = window.setTimeout(() => {\n onCloseAfter?.();\n closeTimeout = undefined;\n listenerSetter.removeAll();\n buttons.forEach((button) => button.element = undefined);\n element.remove();\n }, 300);\n }\n });\n\n return button;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport rootScope from '../../lib/rootScope';\n// import { generatePathData } from \"../../helpers/dom\";\nimport {MyMessage} from '../../lib/appManagers/appMessagesManager';\nimport type Chat from './chat';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport insertInDescendSortedArray from '../../helpers/array/insertInDescendSortedArray';\nimport positionElementByIndex from '../../helpers/dom/positionElementByIndex';\nimport AvatarElement from '../avatar';\nimport {Message} from '../../layer';\nimport {NULL_PEER_ID, REPLIES_PEER_ID} from '../../lib/mtproto/mtproto_config';\nimport {SERVICE_AS_REGULAR, STICKY_OFFSET} from './bubbles';\nimport forEachReverse from '../../helpers/array/forEachReverse';\nimport partition from '../../helpers/array/partition';\nimport noop from '../../helpers/noop';\nimport getMessageThreadId from '../../lib/appManagers/utils/messages/getMessageThreadId';\n\ntype GroupItem = {\n bubble: HTMLElement,\n fromId: PeerId,\n mid: number,\n groupMid?: number,\n timestamp: number,\n dateTimestamp: number,\n mounted: boolean,\n single: boolean,\n group?: BubbleGroup,\n message: Message.message | Message.messageService // use it only to set avatar\n};\n\nclass BubbleGroup {\n container: HTMLElement;\n chat: Chat;\n groups: BubbleGroups;\n items: GroupItem[]; // descend sorted\n avatarContainer: HTMLElement;\n avatarLoadPromise: ReturnType<AvatarElement['updateWithOptions']>;\n avatar: AvatarElement;\n mounted: boolean;\n dateTimestamp: number;\n offset: number;\n\n constructor(chat: Chat, groups: BubbleGroups, dateTimestamp: number) {\n this.container = document.createElement('div');\n this.container.classList.add('bubbles-group');\n this.chat = chat;\n this.groups = groups;\n this.items = [];\n this.dateTimestamp = dateTimestamp;\n this.offset = 0;\n }\n\n createAvatar(message: Message.message | Message.messageService) {\n if(this.avatarLoadPromise) {\n return this.avatarLoadPromise;\n } else if(message._ === 'messageService') {\n return;\n }\n\n this.avatarContainer = document.createElement('div');\n this.avatarContainer.classList.add('bubbles-group-avatar-container');\n ++this.offset;\n\n const fwdFrom = message.fwd_from;\n const fwdFromId = message.fwdFromId;\n const isForwardFromChannel = message.from_id && message.from_id._ === 'peerChannel' && message.fromId === fwdFromId;\n const currentPeerId = this.chat.peerId;\n const avatar = this.avatar = new AvatarElement();\n this.avatar.classList.add('bubbles-group-avatar', 'user-avatar', 'avatar-40'/* , 'can-zoom-fade' */);\n const peerId = ((fwdFrom && (currentPeerId === rootScope.myId || currentPeerId === REPLIES_PEER_ID)) || isForwardFromChannel ? fwdFromId : message.fromId) || NULL_PEER_ID;\n const avatarLoadPromise = this.avatar.updateWithOptions({\n lazyLoadQueue: this.chat.bubbles.lazyLoadQueue,\n peerId,\n peerTitle: !fwdFromId && fwdFrom && fwdFrom.from_name ? /* '🔥 FF 🔥' */fwdFrom.from_name : undefined\n });\n\n // this.avatarLoadPromise = Promise.all([\n // avatarLoadPromise,\n // peerId && peerId.isUser() ? this.chat.managers.appUsersManager.getUser(peerId.toUserId()) : undefined\n // ]).then(([result, user]) => {\n // if(user?.pFlags?.premium) {\n // avatar.classList.add('is-premium', 'tgico-star');\n // }\n\n // return result;\n // });\n this.avatarLoadPromise = avatarLoadPromise;\n\n this.avatarContainer.append(this.avatar);\n this.container.append(this.avatarContainer);\n\n return this.avatarLoadPromise;\n }\n\n get firstTimestamp() {\n return this.firstItem.timestamp;\n }\n\n get firstMid() {\n return this.firstItem.mid;\n }\n\n get firstItem() {\n return this.items[this.items.length - 1];\n }\n\n get lastTimestamp() {\n return this.lastItem.timestamp;\n }\n\n get lastMid() {\n return this.lastItem.mid;\n }\n\n get lastItem() {\n return this.items[0];\n }\n\n updateClassNames() {\n const items = this.items;\n const length = items.length;\n if(!length) {\n return;\n }\n\n // const elements = Array.from(this.container.children);\n // if(this.offset) elements.splice(0, this.offset);\n\n // const length = elements.length;\n // if(!length) {\n // return;\n // }\n\n const first = items[length - 1].bubble;\n\n if(items.length === 1) {\n first.classList.add('is-group-first', 'is-group-last');\n // this.setClipIfNeeded(first);\n return;\n } else {\n first.classList.remove('is-group-last');\n first.classList.add('is-group-first');\n // this.setClipIfNeeded(first, true);\n }\n\n for(let i = 1, _length = length - 1; i < _length; ++i) {\n const bubble = items[i].bubble;\n bubble.classList.remove('is-group-last', 'is-group-first');\n // this.setClipIfNeeded(bubble, true);\n }\n\n const last = items[0].bubble;\n last.classList.remove('is-group-first');\n last.classList.add('is-group-last');\n // this.setClipIfNeeded(last);\n }\n\n insertItem(item: GroupItem) {\n const {items} = this;\n insertInDescendSortedArray(items, item, this.groups.sortGroupItemsKey);\n\n item.group = this;\n if(items.length === 1) {\n this.groups.insertGroup(this);\n }\n }\n\n removeItem(item: GroupItem) {\n indexOfAndSplice(this.items, item);\n\n if(!this.items.length) {\n indexOfAndSplice(this.groups.groups, this);\n }\n\n item.group = undefined;\n }\n\n mount(updateClassNames?: boolean) {\n if(!this.groups.groups.includes(this) || !this.items.length) { // group can be already removed\n debugger;\n\n if(this.mounted) {\n this.onItemUnmount();\n }\n\n return;\n }\n\n const {offset, items} = this;\n const {length} = items;\n forEachReverse(items, (item, idx) => {\n this.mountItem(item, length - 1 - idx, offset);\n });\n\n if(updateClassNames) {\n this.updateClassNames();\n }\n\n this.onItemMount();\n }\n\n mountItem(item: GroupItem, idx = this.items.indexOf(item), offset = this.offset) {\n if(item.mounted) {\n return;\n }\n\n positionElementByIndex(item.bubble, this.container, offset + idx);\n item.mounted = true;\n }\n\n unmountItem(item: GroupItem) {\n if(!item.mounted) {\n return;\n }\n\n item.bubble.remove();\n item.mounted = false;\n this.onItemUnmount();\n }\n\n onItemMount() {\n if(this.mounted) {\n return;\n }\n\n const dateContainer = this.chat.bubbles.getDateContainerByTimestamp(this.dateTimestamp / 1000);\n // const idx = this.groups.indexOf(group);\n const dateGroups = this.groups.groups.filter((_group) => _group.dateTimestamp === this.dateTimestamp);\n const dateGroupsLength = dateGroups.length;\n const idx = dateGroups.indexOf(this);\n const unmountedLength = dateGroups.slice(idx + 1).reduce((acc, v) => acc + (v.mounted ? 0 : 1), 0);\n positionElementByIndex(this.container, dateContainer.container, STICKY_OFFSET + dateGroupsLength - 1 - idx - unmountedLength);\n this.mounted = true;\n }\n\n onItemUnmount() {\n if(!this.mounted) {\n return;\n }\n\n if(!this.items.length) {\n this.container.remove();\n this.chat.bubbles.deleteEmptyDateGroups();\n this.mounted = false;\n } else {\n this.updateClassNames();\n }\n }\n}\n\n// class BubbleGroupItem implements GroupItem {\n// bubble: HTMLElement;\n// fromId: PeerId;\n// mid: number;\n// timestamp: number;\n// dateTimestamp: number;\n// mounted: boolean;\n// single: boolean;\n// group: BubbleGroup;\n\n// constructor(details: GroupItem) {\n// Object.assign(this, details);\n// }\n// }\n\nexport default class BubbleGroups {\n public itemsArr: Array<GroupItem> = []; // descend sorted\n private itemsMap: Map<HTMLElement, GroupItem> = new Map();\n public groups: Array<BubbleGroup> = []; // descend sorted\n private newGroupDiff = 121; // * 121 in scheduled messages\n private sortItemsKey: Extract<keyof GroupItem, 'timestamp' | 'mid'>;\n private sortGroupsKey: Extract<keyof BubbleGroup, 'lastMid' | 'lastTimestamp'>;\n public sortGroupItemsKey: Extract<keyof GroupItem, 'groupMid' | 'timestamp'>;\n\n constructor(private chat: Chat) {\n this.sortItemsKey = chat.type === 'scheduled' ? 'timestamp' : 'mid';\n this.sortGroupsKey = chat.type === 'scheduled' ? 'lastTimestamp' : 'lastMid';\n this.sortGroupItemsKey = /* chat.type === 'scheduled' ? 'timestamp' : */'groupMid';\n }\n\n removeItem(item: GroupItem) {\n item.group?.removeItem(item);\n this.removeItemFromCache(item);\n }\n\n removeAndUnmountBubble(bubble: HTMLElement) {\n const item = this.getItemByBubble(bubble);\n if(!item) {\n if(bubble.parentElement) {\n bubble.remove(); // * can be a placeholder\n }\n\n return false;\n }\n\n const items = this.itemsArr;\n const index = items.indexOf(item);\n const siblings = this.getSiblingsAtIndex(index, items);\n\n const group = item.group;\n this.removeItem(item);\n\n const modifiedGroups: Set<BubbleGroup> = new Set();\n if(group) {\n group.unmountItem(item);\n modifiedGroups.add(group);\n }\n\n const [previousSibling, nextSibling] = siblings;\n if(\n previousSibling &&\n nextSibling &&\n this.canItemsBeGrouped(previousSibling, nextSibling) &&\n previousSibling.group !== nextSibling.group\n ) {\n const group = nextSibling.group;\n this.f(nextSibling.group.items);\n group.onItemUnmount();\n modifiedGroups.add(previousSibling.group);\n this.groupUngrouped();\n }\n\n this.mountUnmountGroups(Array.from(modifiedGroups));\n\n return true;\n }\n\n mountUnmountGroups(groups: BubbleGroup[]) {\n // groups.sort((a, b) => (b.lastItem?.mid ?? 0) - (a.lastItem?.mid ?? 0));\n\n const [toMount, toUnmount] = partition(groups, (group) => !!group.items.length);\n toUnmount.forEach((group) => {\n group.onItemUnmount();\n })\n\n toMount.forEach((group) => {\n group.mount(true);\n });\n\n // toMount.forEach((group) => {\n // group.updateClassNames();\n // });\n }\n\n f(items: GroupItem[], index: number = 0, length = items.length) {\n for(; index < length; ++index) {\n const item = items[index];\n item.mounted = false;\n item.group.removeItem(item);\n --length;\n --index;\n }\n }\n\n getItemByBubble(bubble: HTMLElement) {\n return this.itemsMap.get(bubble);\n }\n\n getLastGroup() {\n return this.groups[0];\n }\n\n changeBubbleMid(bubble: HTMLElement, mid: number) {\n const item = this.getItemByBubble(bubble);\n if(!item) {\n return;\n }\n\n item.mid = mid;\n\n // indexOfAndSplice(item.group.items, item);\n // // const canChangeGroupMid = !item.group.items.length || item.group.items.every((item) => item.groupMid === item.mid);\n // // if(canChangeGroupMid) item.groupMid = mid;\n // item.group.insertItem(item);\n\n indexOfAndSplice(this.itemsArr, item);\n this.insertItemToArray(item, this.itemsArr);\n }\n\n changeItemBubble(item: GroupItem, bubble: HTMLElement) {\n this.itemsMap.delete(item.bubble);\n item.bubble = bubble;\n this.itemsMap.set(bubble, item);\n }\n\n changeBubbleByBubble(from: HTMLElement, to: HTMLElement) {\n const item = this.getItemByBubble(from);\n if(!item) {\n return;\n }\n\n this.changeItemBubble(item, to);\n }\n\n canItemsBeGrouped(item1: GroupItem, item2: GroupItem) {\n return item2.fromId === item1.fromId &&\n Math.abs(item2.timestamp - item1.timestamp) <= this.newGroupDiff &&\n item1.dateTimestamp === item2.dateTimestamp &&\n !item1.single &&\n !item2.single &&\n item1.message.pFlags.out === item2.message.pFlags.out &&\n (!this.chat.isAllMessagesForum || getMessageThreadId(item1.message, true) === getMessageThreadId(item2.message, true)) &&\n (!item1.message.pFlags.out || item1.message.fromId === rootScope.myId);\n }\n\n getSiblingsAtIndex(itemIndex: number, items: GroupItem[]) {\n return [items[itemIndex - 1], items[itemIndex + 1]] as const;\n }\n\n // findGroupSiblingInSiblings(item: GroupItem, siblings: ReturnType<BubbleGroups['getSiblingsAtIndex']>) {\n // return siblings.find((sibling) => sibling && this.canItemsBeGrouped(item, sibling));\n // }\n\n findGroupSiblingByItem(item: GroupItem, items: GroupItem[]) {\n items = items.slice();\n const idx = this.insertItemToArray(item, items);\n // return this.findGroupSiblingInSiblings(item, this.getSiblingsAtIndex(idx, items));\n return this.findGroupSiblingInItems(item, items, idx);\n }\n\n findGroupSiblingInItems(item: GroupItem, items: GroupItem[], index = items.indexOf(item), length = items.length) {\n const previousItem = items[index - 1];\n let siblingGroupedItem: GroupItem;\n if(previousItem?.group && this.canItemsBeGrouped(item, previousItem)) {\n siblingGroupedItem = previousItem;\n } else {\n for(let k = index + 1; k < length; ++k) {\n const nextItem = items[k];\n if(this.canItemsBeGrouped(item, nextItem)) {\n if(nextItem.group) {\n siblingGroupedItem = nextItem;\n }\n } else {\n break;\n }\n }\n }\n\n return siblingGroupedItem;\n }\n\n addItemToGroup(item: GroupItem, group: BubbleGroup) {\n group.insertItem(item);\n this.addItemToCache(item);\n }\n\n insertItemToArray(item: GroupItem, array: GroupItem[]) {\n return insertInDescendSortedArray(array, item, this.sortItemsKey);\n }\n\n insertGroup(group: BubbleGroup) {\n return insertInDescendSortedArray(this.groups, group, this.sortGroupsKey);\n }\n\n addItemToCache(item: GroupItem) {\n this.insertItemToArray(item, this.itemsArr);\n this.itemsMap.set(item.bubble, item);\n }\n\n removeItemFromCache(item: GroupItem) {\n indexOfAndSplice(this.itemsArr, item);\n this.itemsMap.delete(item.bubble);\n }\n\n getMessageFromId(message: MyMessage) {\n let fromId = /* (this.chat.peerId.isAnyChat() && message.viaBotId) || */message.fromId;\n\n // fix for saved messages forward to self\n if(fromId === rootScope.myId && message.peerId === rootScope.myId && (message as Message.message).fwdFromId === fromId) {\n fromId = fromId.toPeerId(true);\n }\n\n return fromId;\n }\n\n createItem(bubble: HTMLElement, message: MyMessage) {\n const single = !(message._ === 'message' || (message.action && SERVICE_AS_REGULAR.has(message.action._)));\n const {mid, date: timestamp} = message;\n const {dateTimestamp} = this.chat.bubbles.getDateForDateContainer(timestamp);\n const item: GroupItem = {\n mid,\n groupMid: this.chat.type === 'scheduled' ? +`${(timestamp * 1000 - dateTimestamp) / 1000}.${mid}` : mid,\n fromId: this.getMessageFromId(message),\n bubble,\n // timestamp: this.chat.type === 'scheduled' ? +`${(timestamp * 1000 - dateTimestamp) / 1000}.${mid}` : timestamp,\n timestamp,\n dateTimestamp,\n mounted: false,\n single,\n message\n };\n\n return item;\n }\n\n splitSiblingsOnGrouping(siblings: ReturnType<BubbleGroups['getSiblingsAtIndex']>) {\n const [previousSibling, nextSibling] = siblings;\n const previousGroup = previousSibling?.group;\n const nextGroup = nextSibling?.group;\n\n if(!previousGroup) {\n return;\n }\n\n // will refresh group\n // if(previousGroup === nextGroup) {\n const items = previousGroup.items;\n const index = items.indexOf(previousSibling) + 1;\n const length = items.length;\n if(index === length) {\n return;\n }\n\n const modifiedGroups: BubbleGroup[] = [previousGroup];\n // if(previousGroup !== nextGroup && nextGroup) {\n // modifiedGroups.push(nextGroup);\n // }\n\n this.f(items, index, length);\n return modifiedGroups;\n // }\n }\n\n prepareForGrouping(bubble: HTMLElement, message: MyMessage) {\n const foundItem = this.getItemByBubble(bubble);\n if(foundItem) { // should happen only on edit\n // debugger;\n return;\n }\n\n const item = this.createItem(bubble, message);\n this.addItemToCache(item);\n }\n\n groupUngrouped() {\n const items = this.itemsArr;\n const length = items.length;\n const modifiedGroups: Set<BubbleGroup> = new Set();\n // for(let i = length - 1; i >= 0; --i) {\n for(let i = 0; i < length; ++i) {\n const item = items[i];\n if(item.group) {\n continue;\n }\n\n let hadGroup = true;\n const siblings = this.getSiblingsAtIndex(i, items);\n const siblingGroupedItem = this.findGroupSiblingInItems(item, items, i, length);\n\n // const foundItem = this.findGroupSiblingInSiblings(item, siblings);\n const foundItem = siblingGroupedItem;\n const group = foundItem?.group ?? (hadGroup = false, new BubbleGroup(this.chat, this, item.dateTimestamp));\n\n modifiedGroups.add(group);\n group.insertItem(item);\n\n if(!hadGroup) {\n const splittedGroups = this.splitSiblingsOnGrouping(siblings);\n if(splittedGroups) {\n splittedGroups.forEach((group) => modifiedGroups.add(group));\n }\n }\n }\n\n return modifiedGroups;\n }\n\n // addBubble(bubble: HTMLElement, message: MyMessage, unmountIfFound?: boolean) {\n // const oldItem = this.getItemByBubble(bubble);\n // if(unmountIfFound) { // updating position\n // this.removeAndUnmountBubble(bubble);\n // } else if(oldItem) { // editing\n // const group = oldItem.group;\n // this.changeItemBubble(oldItem, bubble);\n // oldItem.mounted = false;\n\n // return {item: oldItem, group};\n // }\n\n // const item = this.createItem(bubble, message);\n\n // const foundItem = this.findSameGroupItem(item, this.itemsArr);\n\n // const group = foundItem?.group ?? new BubbleGroup(this.chat, this, item.dateTimestamp);\n // this.addItemToGroup(item, group);\n\n // return {item, group};\n // }\n\n /* setClipIfNeeded(bubble: HTMLDivElement, remove = false) {\n //console.log('setClipIfNeeded', bubble, remove);\n const className = bubble.className;\n if(className.includes('is-message-empty') && (className.includes('photo') || className.includes('video'))) {\n let container = bubble.querySelector('.bubble__media-container') as SVGSVGElement;\n //console.log('setClipIfNeeded', bubble, remove, container);\n if(!container) return;\n\n try {\n Array.from(container.children).forEach((object) => {\n if(object instanceof SVGDefsElement) return;\n\n if(remove) {\n object.removeAttributeNS(null, 'clip-path');\n } else {\n let clipId = container.dataset.clipId;\n let path = container.firstElementChild.firstElementChild.lastElementChild as SVGPathElement;\n let width = +object.getAttributeNS(null, 'width');\n let height = +object.getAttributeNS(null, 'height');\n let isOut = className.includes('is-out');\n let isReply = className.includes('is-reply');\n let d = '';\n\n //console.log('setClipIfNeeded', object, width, height, isOut);\n\n let tr: number, tl: number;\n if(className.includes('forwarded') || isReply) {\n tr = tl = 0;\n } else if(isOut) {\n tr = className.includes('is-group-first') ? 12 : 6;\n tl = 12;\n } else {\n tr = 12;\n tl = className.includes('is-group-first') ? 12 : 6;\n }\n\n if(isOut) {\n d = generatePathData(0, 0, width - 9, height, tl, tr, 0, 12);\n } else {\n d = generatePathData(9, 0, width - 9, height, tl, tr, 12, 0);\n }\n\n path.setAttributeNS(null, 'd', d);\n object.setAttributeNS(null, 'clip-path', 'url(#' + clipId + ')');\n }\n });\n } catch(err) {}\n }\n } */\n\n // updateGroupByMessageId(mid: number) {\n // const item = this.itemsArr.find((g) => g.mid === mid);\n // if(item) {\n // item.group.updateGroup();\n // }\n // }\n\n cleanup() {\n this.itemsArr = [];\n this.groups = [];\n this.itemsMap.clear();\n }\n\n // findIncorrentPositions() {\n // var bubbles = Array.from(this.chat.bubbles.chatInner.querySelectorAll('.bubbles-group .bubble')).reverse();\n // var items = this.itemsArr;\n // for(var i = 0, length = items.length; i < length; ++i) {\n // const item = items[i];\n // const foundBubble = bubbles[i];\n // if(item.bubble !== foundBubble) {\n // console.log('incorrect position', i, item, foundBubble);\n // // debugger;\n // // break;\n // }\n // }\n // }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {Message} from '../../layer';\nimport rootScope from '../../lib/rootScope';\nimport ripple from '../ripple';\nimport I18n from '../../lib/langPack';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport StackedAvatars from '../stackedAvatars';\nimport formatNumber from '../../helpers/number/formatNumber';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getPeerId from '../../lib/appManagers/utils/peers/getPeerId';\nimport type LazyLoadQueue from '../lazyLoadQueue';\n\nconst TAG_NAME = 'replies-element';\n\nrootScope.addEventListener('replies_updated', (message) => {\n (Array.from(document.querySelectorAll(TAG_NAME + `[data-post-key=\"${message.peerId}_${message.mid}\"]`)) as RepliesElement[]).forEach((element) => {\n element.message = message;\n element.render();\n });\n});\n\nexport default class RepliesElement extends HTMLElement {\n public message: Message.message;\n public type: 'footer' | 'beside';\n public loadPromises: Promise<any>[];\n public lazyLoadQueue: LazyLoadQueue;\n public stackedAvatars: StackedAvatars;\n public text: I18n.IntlElement;\n public managers: AppManagers;\n\n private updated = false;\n\n constructor() {\n super();\n this.managers = rootScope.managers;\n }\n\n public init() {\n this.render();\n this.dataset.postKey = this.message.peerId + '_' + this.message.mid;\n this.classList.add('replies', 'replies-' + this.type);\n }\n\n public render() {\n const replies = this.message.replies;\n\n if(this.type === 'footer') {\n let leftPart: HTMLElement;\n if(this.firstElementChild) {\n leftPart = this.firstElementChild as HTMLElement;\n }\n\n if(replies?.recent_repliers) {\n if(leftPart && !leftPart.classList.contains('replies-footer-avatars')) {\n this.replaceChildren();\n leftPart = null;\n }\n\n if(!this.stackedAvatars) {\n this.stackedAvatars = new StackedAvatars({\n lazyLoadQueue: this.lazyLoadQueue,\n avatarSize: 30\n });\n\n this.stackedAvatars.container.classList.add('replies-footer-avatars');\n }\n\n leftPart = this.stackedAvatars.container;\n\n this.stackedAvatars.render(replies.recent_repliers.map((peer) => getPeerId(peer)), this.loadPromises);\n } else {\n if(leftPart && !leftPart.classList.contains('tgico-comments')) {\n leftPart.remove();\n leftPart = null;\n }\n\n if(!leftPart) {\n leftPart = document.createElement('span');\n leftPart.classList.add('tgico-comments');\n }\n }\n\n if(!leftPart.parentElement) {\n this.prepend(leftPart);\n }\n\n if(!this.text) {\n this.text = new I18n.IntlElement();\n }\n\n const text = this.text;\n if(replies) {\n if(replies.replies) {\n text.compareAndUpdate({key: 'Comments', args: [replies.replies]});\n } else {\n text.compareAndUpdate({key: 'LeaveAComment'});\n }\n } else {\n text.compareAndUpdate({key: 'ViewInChat'});\n }\n\n if(replies) {\n // const historyStorage = appMessagesManager.getHistoryStorage(replies.channel_id.toPeerId(true));\n let isUnread = false;\n if(replies.replies) {\n if(replies.read_max_id !== undefined && replies.max_id !== undefined) {\n isUnread = replies.read_max_id < replies.max_id;\n }/* else {\n isUnread = !historyStorage.readMaxId || historyStorage.readMaxId < (replies.max_id || 0);\n } */\n }\n this.classList.toggle('is-unread', isUnread);\n }\n\n let textSpan = this.children[1] as HTMLElement;\n if(!textSpan) {\n textSpan = document.createElement('span');\n textSpan.classList.add('replies-footer-text');\n\n const iconSpan = document.createElement('span');\n iconSpan.classList.add('tgico-next');\n\n const rippleContainer = document.createElement('div');\n ripple(rippleContainer);\n\n this.append(textSpan, iconSpan, rippleContainer);\n }\n\n replaceContent(textSpan, text.element);\n } else {\n this.classList.add('bubble-beside-button');\n this.innerHTML = `<span class=\"tgico-commentssticker\"></span><span class=\"replies-beside-text\">${replies?.replies ? formatNumber(replies.replies, 0) : ''}</span>`;\n }\n\n if(replies && !this.updated && !this.message.pFlags.is_outgoing) {\n this.managers.appMessagesManager.subscribeRepliesThread(this.message.peerId, this.message.mid);\n this.managers.appMessagesManager.updateMessage(this.message.peerId, this.message.mid, 'replies_updated');\n this.updated = true;\n }\n\n if(this.loadPromises) {\n this.loadPromises = undefined;\n }\n }\n}\n\ncustomElements.define(TAG_NAME, RepliesElement);\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {formatTime, getFullDate} from '../../helpers/date';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport formatNumber from '../../helpers/number/formatNumber';\nimport {Message} from '../../layer';\nimport getPeerId from '../../lib/appManagers/utils/peers/getPeerId';\nimport {i18n, _i18n} from '../../lib/langPack';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport rootScope from '../../lib/rootScope';\nimport type LazyLoadQueue from '../lazyLoadQueue';\nimport PeerTitle from '../peerTitle';\nimport wrapReply from '../wrappers/reply';\nimport Chat, {ChatType} from './chat';\nimport RepliesElement from './replies';\n\nconst NBSP = '&nbsp;';\n\nconst makeEdited = () => {\n const edited = document.createElement('i');\n edited.classList.add('edited');\n _i18n(edited, 'EditedMessage');\n return edited;\n};\n\nconst makeSponsored = () => i18n('SponsoredMessage');\n\nexport namespace MessageRender {\n /* export const setText = () => {\n\n }; */\n\n export const setTime = (options: {\n chatType: ChatType,\n message: Message.message | Message.messageService,\n reactionsMessage?: Message.message\n }) => {\n const {chatType, message} = options;\n const date = new Date(message.date * 1000);\n const args: (HTMLElement | string)[] = [];\n\n let editedSpan: HTMLElement,\n sponsoredSpan: HTMLElement;\n // reactionsElement: ReactionsElement,\n // reactionsMessage: Message.message;\n\n const isSponsored = !!(message as Message.message).pFlags.sponsored;\n const isMessage = !('action' in message) && !isSponsored;\n // let hasReactions: boolean;\n\n const time: HTMLElement = isSponsored ? undefined : formatTime(date);\n if(isMessage) {\n if(message.views) {\n const postAuthor = message.post_author || message.fwd_from?.post_author;\n\n const postViewsSpan = document.createElement('span');\n postViewsSpan.classList.add('post-views');\n postViewsSpan.textContent = formatNumber(message.views, 1);\n\n const channelViews = document.createElement('i');\n channelViews.classList.add('tgico-channelviews', 'time-icon');\n\n args.push(postViewsSpan, channelViews);\n if(postAuthor) {\n const span = document.createElement('span');\n setInnerHTML(span, wrapEmojiText(postAuthor));\n span.insertAdjacentHTML('beforeend', ',' + NBSP)\n args.push(span);\n }\n }\n\n if(message.edit_date && chatType !== 'scheduled' && !message.pFlags.edit_hide) {\n args.unshift(editedSpan = makeEdited());\n }\n\n if(chatType !== 'pinned' && message.pFlags.pinned) {\n const i = document.createElement('i');\n i.classList.add('tgico-pinnedchat', 'time-icon');\n args.unshift(i);\n }\n\n // if(USER_REACTIONS_INLINE && message.peer_id._ === 'peerUser'/* && message.reactions?.results?.length */) {\n // hasReactions = true;\n\n // reactionsMessage = options.reactionsMessage;\n // reactionsElement = new ReactionsElement();\n // reactionsElement.init(reactionsMessage, 'inline', true);\n // reactionsElement.render();\n // args.unshift(reactionsElement);\n // }\n } else if(isSponsored) {\n args.push(sponsoredSpan = makeSponsored());\n }\n\n if(time) {\n args.push(time);\n }\n\n let title = isSponsored ? undefined : getFullDate(date);\n if(isMessage) {\n title += (message.edit_date && !message.pFlags.edit_hide ? `\\nEdited: ${getFullDate(new Date(message.edit_date * 1000))}` : '') +\n (message.fwd_from ? `\\nOriginal: ${getFullDate(new Date(message.fwd_from.date * 1000))}` : '');\n }\n\n const timeSpan = document.createElement('span');\n timeSpan.classList.add('time', 'tgico');\n // if(title) timeSpan.title = title;\n timeSpan.append(...args);\n\n const inner = document.createElement('div');\n inner.classList.add('inner', 'tgico');\n if(title) inner.title = title;\n\n let clonedArgs = args;\n if(editedSpan) {\n clonedArgs[clonedArgs.indexOf(editedSpan)] = makeEdited();\n }\n if(sponsoredSpan) {\n clonedArgs[clonedArgs.indexOf(sponsoredSpan)] = makeSponsored();\n }\n // if(reactionsElement) {\n // const _reactionsElement = clonedArgs[clonedArgs.indexOf(reactionsElement)] = new ReactionsElement();\n // _reactionsElement.init(reactionsMessage, 'inline');\n // _reactionsElement.render();\n // }\n clonedArgs = clonedArgs.map((a) => a instanceof HTMLElement && !a.classList.contains('i18n') && !a.classList.contains('reactions') ? a.cloneNode(true) as HTMLElement : a);\n if(time) {\n clonedArgs[clonedArgs.length - 1] = formatTime(date); // clone time\n }\n inner.append(...clonedArgs);\n\n timeSpan.append(inner);\n\n return timeSpan;\n };\n\n export const renderReplies = ({bubble, bubbleContainer, message, messageDiv, loadPromises, lazyLoadQueue}: {\n bubble: HTMLElement,\n bubbleContainer: HTMLElement,\n message: Message.message,\n messageDiv: HTMLElement,\n loadPromises?: Promise<any>[],\n lazyLoadQueue?: LazyLoadQueue\n }) => {\n const isFooter = !bubble.classList.contains('sticker') && !bubble.classList.contains('emoji-big') && !bubble.classList.contains('round');\n const repliesFooter = new RepliesElement();\n repliesFooter.message = message;\n repliesFooter.type = isFooter ? 'footer' : 'beside';\n repliesFooter.loadPromises = loadPromises;\n repliesFooter.lazyLoadQueue = lazyLoadQueue;\n repliesFooter.init();\n bubbleContainer.prepend(repliesFooter);\n return isFooter;\n };\n\n export const setReply = async({chat, bubble, bubbleContainer, message}: {\n chat: Chat,\n bubble: HTMLElement,\n bubbleContainer?: HTMLElement,\n message: Message.message\n }) => {\n const isReplacing = !bubbleContainer;\n if(isReplacing) {\n bubbleContainer = bubble.querySelector('.bubble-content');\n }\n\n const currentReplyDiv = isReplacing ? bubbleContainer.querySelector('.reply') : null;\n if(!message.reply_to_mid) {\n currentReplyDiv?.remove();\n\n bubble.classList.remove('is-reply');\n return;\n }\n\n\n const replyToPeerId = message.reply_to.reply_to_peer_id ? getPeerId(message.reply_to.reply_to_peer_id) : chat.peerId;\n\n const originalMessage = await rootScope.managers.appMessagesManager.getMessageByPeer(replyToPeerId, message.reply_to_mid);\n let originalPeerTitle: string | HTMLElement;\n\n // ///////this.log('message to render reply', originalMessage, originalPeerTitle, bubble, message);\n\n let titlePeerId: PeerId;\n // need to download separately\n if(!originalMessage) {\n // ////////this.log('message to render reply empty, need download', message, message.reply_to_mid);\n rootScope.managers.appMessagesManager.fetchMessageReplyTo(message);\n chat.bubbles.needUpdate.push({replyToPeerId, replyMid: message.reply_to_mid, mid: message.mid});\n\n originalPeerTitle = i18n('Loading');\n } else {\n const originalMessageFwdFromId = (originalMessage as Message.message).fwdFromId;\n titlePeerId = message.fwdFromId && message.fwdFromId === originalMessageFwdFromId ? message.fwdFromId : originalMessage.fromId || originalMessageFwdFromId;\n originalPeerTitle = new PeerTitle({\n peerId: titlePeerId,\n dialog: false,\n onlyFirstName: false,\n plainText: false\n }).element;\n }\n\n const {container, fillPromise} = wrapReply(originalPeerTitle, undefined, chat.animationGroup, originalMessage, chat.isAnyGroup ? titlePeerId : undefined);\n await fillPromise;\n if(currentReplyDiv) {\n if(currentReplyDiv.classList.contains('floating-part')) {\n container.classList.add('floating-part');\n }\n currentReplyDiv.replaceWith(container);\n } else {\n bubbleContainer.append(container);\n }\n // bubbleContainer.insertBefore(, nameContainer);\n bubble.classList.add('is-reply');\n\n return container;\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport type IntersectionTarget = Element;\nexport type IntersectionCallback = (entry: IntersectionObserverEntry) => void;\n\nexport default class SuperIntersectionObserver {\n private observing: Map<IntersectionTarget, Set<IntersectionCallback>>;\n private observingQueue: SuperIntersectionObserver['observing'];\n private observer: IntersectionObserver;\n private freezedObservingNew: boolean;\n\n constructor(init?: IntersectionObserverInit) {\n this.observing = new Map();\n this.observingQueue = new Map();\n this.freezedObservingNew = false;\n\n this.observer = new IntersectionObserver((entries) => {\n const observing = this.observing;\n for(let i = 0, length = entries.length; i < length; ++i) {\n const entry = entries[i];\n const callbacks = observing.get(entry.target);\n if(!callbacks) {\n console.error('intersection process no callbacks:', entry);\n debugger;\n continue;\n }\n\n for(const callback of callbacks) {\n try {\n callback(entry);\n } catch(err) {\n console.error('intersection process callback error:', err);\n }\n }\n }\n }, init);\n }\n\n public disconnect() {\n this.observing.clear();\n this.observingQueue.clear();\n this.observer.disconnect();\n }\n\n public toggleObservingNew(value: boolean) {\n if(this.freezedObservingNew === value) {\n return;\n }\n\n this.freezedObservingNew = value;\n\n const queue = this.observingQueue;\n if(!value && queue.size) {\n for(const [target, callbacks] of queue) {\n for(const callback of callbacks) {\n this.observe(target, callback);\n }\n }\n\n queue.clear();\n }\n }\n\n public has(target: IntersectionTarget, callback: IntersectionCallback, observing = this.observing) {\n const callbacks = observing.get(target);\n return !!(callbacks && callbacks.has(callback));\n }\n\n public observe(target: IntersectionTarget, callback: IntersectionCallback) {\n if(this.freezedObservingNew && this.has(target, callback)) {\n return;\n }\n\n const observing = this.freezedObservingNew ? this.observingQueue : this.observing;\n let callbacks = observing.get(target);\n if(callbacks && callbacks.has(callback)) {\n return;\n }\n\n if(!callbacks) {\n callbacks = new Set();\n observing.set(target, callbacks);\n\n if(observing === this.observing) {\n this.observer.observe(target);\n }\n }\n\n callbacks.add(callback);\n }\n\n public unobserve(target: IntersectionTarget, callback: IntersectionCallback) {\n const observing = this.freezedObservingNew && !this.has(target, callback) ? this.observingQueue : this.observing;\n const callbacks = observing.get(target);\n if(!callbacks) {\n return;\n }\n\n callbacks.delete(callback);\n if(!callbacks.size) {\n observing.delete(target);\n this.observer.unobserve(target);\n }\n }\n}\n","import type {MyDocument} from '../../appDocsManager';\nimport type {MyMessage} from '../../appMessagesManager';\nimport {Message, MessageMedia} from '../../../../layer';\n\nexport default function isMentionUnread(message: MyMessage) {\n if(!message) {\n return false;\n }\n\n const doc = ((message as Message.message).media as MessageMedia.messageMediaDocument)?.document as MyDocument;\n return !!(\n message.pFlags.media_unread &&\n message.pFlags.mentioned &&\n (\n !doc ||\n !(['voice', 'round'] as MyDocument['type'][]).includes(doc.type)\n )\n );\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {ChatAutoDownloadSettings} from '../../helpers/autoDownload';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport {Middleware} from '../../helpers/middleware';\nimport {Document, Message, MessageMedia, Photo, PhotoSize} from '../../layer';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getMediaFromMessage from '../../lib/appManagers/utils/messages/getMediaFromMessage';\nimport choosePhotoSize from '../../lib/appManagers/utils/photos/choosePhotoSize';\nimport rootScope from '../../lib/rootScope';\nimport {AnimationItemGroup} from '../animationIntersector';\nimport Chat from '../chat/chat';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport prepareAlbum from '../prepareAlbum';\nimport wrapMediaSpoiler from './mediaSpoiler';\nimport wrapPhoto from './photo';\nimport wrapVideo from './video';\n\nexport default function wrapAlbum({messages, attachmentDiv, middleware, uploading, lazyLoadQueue, isOut, chat, loadPromises, autoDownload, managers = rootScope.managers, animationGroup}: {\n messages: Message.message[],\n attachmentDiv: HTMLElement,\n middleware?: Middleware,\n lazyLoadQueue?: LazyLoadQueue,\n uploading?: boolean,\n isOut: boolean,\n chat: Chat,\n loadPromises?: Promise<any>[],\n autoDownload?: ChatAutoDownloadSettings,\n managers?: AppManagers,\n animationGroup?: AnimationItemGroup\n}) {\n const items: {size: PhotoSize.photoSize, media: Photo.photo | Document.document, message: Message.message}[] = [];\n\n // !lowest msgID will be the FIRST in album\n for(const message of messages) {\n const media = getMediaFromMessage(message, true);\n\n const size: any = media._ === 'photo' ? choosePhotoSize(media, 480, 480) : {w: media.w, h: media.h};\n items.push({size, media, message});\n }\n\n /* // * pending\n if(storage[0] < 0) {\n items.reverse();\n } */\n\n prepareAlbum({\n container: attachmentDiv,\n items: items.map((i) => ({w: i.size.w, h: i.size.h})),\n maxWidth: mediaSizes.active.album.width,\n minWidth: 100,\n spacing: 2,\n forMedia: true\n });\n\n const {width, height} = attachmentDiv.style;\n const containerWidth = parseInt(width);\n const containerHeight = parseInt(height);\n\n items.forEach((item, idx) => {\n const {size, media, message} = item;\n\n const messageMedia = message.media;\n const hasSpoiler = !!(messageMedia as MessageMedia.messageMediaPhoto | MessageMedia.messageMediaDocument).pFlags?.spoiler;\n\n const div = attachmentDiv.children[idx] as HTMLElement;\n div.dataset.mid = '' + message.mid;\n div.dataset.peerId = '' + message.peerId;\n const mediaDiv = div.firstElementChild as HTMLElement;\n const isPhoto = media._ === 'photo';\n let thumbPromise: Promise<any>;\n if(isPhoto) {\n thumbPromise = wrapPhoto({\n photo: media,\n message,\n container: mediaDiv,\n boxWidth: 0,\n boxHeight: 0,\n isOut,\n lazyLoadQueue,\n middleware,\n size,\n loadPromises,\n autoDownloadSize: autoDownload.photo,\n managers\n });\n } else {\n thumbPromise = wrapVideo({\n doc: media,\n container: mediaDiv,\n message,\n boxWidth: 0,\n boxHeight: 0,\n withTail: false,\n isOut,\n lazyLoadQueue,\n middleware,\n loadPromises,\n autoDownload,\n managers,\n noAutoplayAttribute: hasSpoiler\n });\n }\n\n if(thumbPromise) {\n loadPromises?.push(thumbPromise);\n }\n\n if(hasSpoiler) {\n const promise = (thumbPromise || Promise.resolve()).then(async() => {\n if(!middleware()) {\n return;\n }\n\n const {width, height} = div.style;\n const itemWidth = +width.slice(0, -1) / 100 * containerWidth;\n const itemHeight = +height.slice(0, -1) / 100 * containerHeight;\n const container = await wrapMediaSpoiler({\n media,\n animationGroup,\n middleware,\n width: itemWidth,\n height: itemHeight\n });\n\n if(!middleware()) {\n return;\n }\n\n mediaDiv.append(container);\n });\n\n loadPromises?.push(promise);\n }\n });\n}\n","import {Document, Message, MessageMedia} from '../../../../layer';\n\nexport default function getMediaDurationFromMessage(message: Message.message) {\n if(!message) return undefined;\n const doc = (message.media as MessageMedia.messageMediaDocument)?.document as Document.document;\n const duration = ((['voice', 'audio', 'video'] as Document.document['type'][]).includes(doc?.type) && doc.duration) || undefined;\n return duration;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTab} from '../../slider';\nimport appSidebarRight from '..';\nimport {roundPercents} from '../../poll';\nimport appDialogsManager from '../../../lib/appManagers/appDialogsManager';\nimport {i18n} from '../../../lib/langPack';\nimport setInnerHTML from '../../../helpers/dom/setInnerHTML';\nimport wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';\nimport Button from '../../button';\nimport {Message, MessageMedia} from '../../../layer';\n\nexport default class AppPollResultsTab extends SliderSuperTab {\n private resultsDiv: HTMLElement;\n\n public async init(message: Message.message) {\n this.container.id = 'poll-results-container';\n this.container.classList.add('chatlist-container');\n\n this.resultsDiv = document.createElement('div');\n this.resultsDiv.classList.add('poll-results');\n this.scrollable.append(this.resultsDiv);\n\n const poll = await this.managers.appPollsManager.getPoll((message.media as MessageMedia.messageMediaPoll).poll.id);\n\n this.setTitle(poll.poll.pFlags.quiz ? 'PollResults.Title.Quiz' : 'PollResults.Title.Poll');\n\n const title = document.createElement('h3');\n setInnerHTML(title, wrapEmojiText(poll.poll.question));\n\n const percents = poll.results.results.map((v) => v.voters / poll.results.total_voters * 100);\n roundPercents(percents);\n\n const fragment = document.createDocumentFragment();\n poll.results.results.forEach((result, idx) => {\n if(!result.voters) return;\n\n const hr = document.createElement('hr');\n\n const answer = poll.poll.answers[idx];\n\n // Head\n const answerEl = document.createElement('div');\n answerEl.classList.add('poll-results-answer');\n\n const answerTitle = document.createElement('div');\n setInnerHTML(answerTitle, wrapEmojiText(answer.text));\n\n const answerPercents = document.createElement('div');\n answerPercents.innerText = Math.round(percents[idx]) + '%';\n\n answerEl.append(answerTitle, answerPercents);\n\n // Humans\n const list = appDialogsManager.createChatList();\n list.classList.add('poll-results-voters');\n\n appDialogsManager.setListClickListener(list, () => {\n appSidebarRight.onCloseBtnClick();\n }, undefined, true);\n\n list.style.minHeight = Math.min(result.voters, 4) * 48 + 'px';\n\n fragment.append(hr, answerEl, list);\n\n let offset: string, limit = 4, loading = false, left = Math.max(0, result.voters - 4);\n const load = () => {\n if(loading) return;\n loading = true;\n\n this.managers.appPollsManager.getVotes(message, answer.option, offset, limit).then((votesList) => {\n votesList.votes.forEach((vote) => {\n const {dom} = appDialogsManager.addDialogNew({\n peerId: vote.user_id.toPeerId(false),\n container: list,\n rippleEnabled: false,\n meAsSaved: false,\n avatarSize: 'small'\n });\n dom.lastMessageSpan.parentElement.remove();\n });\n\n if(offset) {\n left = Math.max(0, left - votesList.votes.length);\n\n if(left) {\n (showMore.lastElementChild as HTMLElement).replaceWith(i18n('PollResults.LoadMore', [Math.min(20, left)]));\n }\n }\n\n offset = votesList.next_offset;\n limit = 20;\n\n if(!left || !votesList.votes.length) {\n showMore.remove();\n }\n }).finally(() => {\n loading = false;\n });\n };\n\n const showMore = Button('poll-results-more btn btn-primary btn-transparent', {icon: 'down'});\n showMore.addEventListener('click', load);\n showMore.append(i18n('PollResults.LoadMore', [Math.min(20, left)]));\n\n fragment.append(showMore);\n\n load();\n });\n\n this.resultsDiv.append(title, fragment);\n\n appSidebarRight.toggleSidebar(true).then(() => {\n /* appPollsManager.getVotes(mid).then((votes) => {\n console.log('gOt VotEs', votes);\n }); */\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport mediaSizes from '../helpers/mediaSizes';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport appImManager from '../lib/appManagers/appImManager';\nimport rootScope from '../lib/rootScope';\nimport ripple from './ripple';\nimport appSidebarRight from './sidebarRight';\nimport AppPollResultsTab from './sidebarRight/tabs/pollResults';\nimport {FormatterArguments, i18n, LangPackKey} from '../lib/langPack';\nimport {fastRaf} from '../helpers/schedulers';\nimport SetTransition from './singleTransition';\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {attachClickEvent, simulateClickEvent} from '../helpers/dom/clickEvent';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport windowSize from '../helpers/windowSize';\nimport {Message, MessageMedia, Poll, PollResults} from '../layer';\nimport toHHMMSS from '../helpers/string/toHHMMSS';\nimport StackedAvatars from './stackedAvatars';\nimport setInnerHTML from '../helpers/dom/setInnerHTML';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport wrapEmojiText from '../lib/richTextProcessor/wrapEmojiText';\nimport wrapRichText from '../lib/richTextProcessor/wrapRichText';\nimport liteMode from '../helpers/liteMode';\n\nlet lineTotalLength = 0;\nconst tailLength = 9;\nconst times = 10;\nconst fullTime = 340;\nconst oneTime = fullTime / times;\n\nexport const roundPercents = (percents: number[]) => {\n // console.log('roundPercents before percents:', percents);\n\n const sum = percents.reduce((acc, p) => acc + Math.round(p), 0);\n if(sum > 100) {\n const diff = sum - 100;\n const length = percents.length;\n for(let i = 0; i < diff; ++i) {\n let minIndex = -1, minRemainder = 1;\n for(let k = 0; k < length; ++k) {\n const remainder = percents[k] % 1;\n if(remainder >= 0.5 && remainder < minRemainder) {\n minRemainder = remainder;\n minIndex = k;\n }\n }\n\n if(minIndex === -1) {\n // throw new Error('lol chto');\n return;\n }\n\n percents[minIndex] -= minRemainder;\n }\n } else if(sum < 100) {\n const diff = 100 - sum;\n const length = percents.length;\n for(let i = 0; i < diff; ++i) {\n let minIndex = -1, maxRemainder = 0;\n for(let k = 0; k < length; ++k) {\n const remainder = percents[k] % 1;\n if(remainder < 0.5 && remainder > maxRemainder) {\n maxRemainder = remainder;\n minIndex = k;\n }\n }\n\n if(minIndex === -1) {\n // throw new Error('lol chto');\n return;\n }\n\n percents[minIndex] += 1 - maxRemainder;\n }\n }\n\n // console.log('roundPercents after percents:', percents);\n};\n\n/* const connectedPolls: {id: string, element: PollElement}[] = [];\nrootScope.on('poll_update', (e) => {\n const {poll, results} = e as {poll: Poll, results: PollResults};\n\n //console.log('poll_update', poll, results);\n for(const connected of connectedPolls) {\n if(connected.id === poll.id) {\n const pollElement = connected.element;\n pollElement.isClosed = !!poll.pFlags.closed;\n pollElement.performResults(results, poll.chosenIndexes);\n }\n }\n}); */\n\nrootScope.addEventListener('poll_update', ({poll, results}) => {\n const pollElements = Array.from(document.querySelectorAll(`poll-element[poll-id=\"${poll.id}\"]`)) as PollElement[];\n pollElements.forEach((pollElement) => {\n // console.log('poll_update', poll, results);\n pollElement.isClosed = !!poll.pFlags.closed;\n pollElement.performResults(results, poll.chosenIndexes);\n });\n});\n\nmediaSizes.addEventListener('resize', () => {\n PollElement.setMaxLength();\n PollElement.resizePolls();\n});\n\nmediaSizes.addEventListener('changeScreen', () => {\n PollElement.setMaxLength();\n});\n\nconst hideQuizHint = (element: HTMLElement, onHide: () => void, timeout: number) => {\n element.classList.remove('active');\n\n clearTimeout(timeout);\n setTimeout(() => {\n onHide();\n element.remove();\n\n if(prevQuizHint === element && prevQuizHintOnHide === onHide && prevQuizHintTimeout === timeout) {\n prevQuizHint = prevQuizHintOnHide = null;\n prevQuizHintTimeout = 0;\n }\n }, 200);\n};\n\nlet prevQuizHint: HTMLElement, prevQuizHintOnHide: () => void, prevQuizHintTimeout: number;\nlet isListenerSet = false;\nconst setQuizHint = (solution: string, solution_entities: any[], onHide: () => void) => {\n if(prevQuizHint) {\n hideQuizHint(prevQuizHint, prevQuizHintOnHide, prevQuizHintTimeout);\n }\n\n const element = document.createElement('div');\n element.classList.add('quiz-hint');\n\n const container = document.createElement('div');\n container.classList.add('container', 'tgico');\n\n const textEl = document.createElement('div');\n textEl.classList.add('text');\n\n container.append(textEl);\n element.append(container);\n\n setInnerHTML(textEl, wrapRichText(solution, {entities: solution_entities}));\n appImManager.chat.bubbles.container.append(element);\n\n void element.offsetLeft; // reflow\n element.classList.add('active');\n\n prevQuizHint = element;\n prevQuizHintOnHide = onHide;\n prevQuizHintTimeout = window.setTimeout(() => {\n hideQuizHint(element, onHide, prevQuizHintTimeout);\n }, IS_TOUCH_SUPPORTED ? 5000 : 7000);\n\n if(!isListenerSet) {\n isListenerSet = true;\n appImManager.addEventListener('peer_changed', () => {\n if(prevQuizHint) {\n hideQuizHint(prevQuizHint, prevQuizHintOnHide, prevQuizHintTimeout);\n }\n });\n }\n};\n\nexport default class PollElement extends HTMLElement {\n public static MAX_OFFSET = -46.5;\n public static MAX_LENGTH = 0;\n public svgLines: SVGSVGElement[];\n private numberDivs: HTMLDivElement[];\n private answerDivs: HTMLDivElement[];\n private descDiv: HTMLElement;\n private typeDiv: HTMLElement;\n private avatarsDiv: HTMLElement;\n private viewResults: HTMLElement;\n private votersCountDiv: HTMLDivElement;\n\n // private maxLength: number;\n // private maxLengths: number[];\n private maxPercents: number[];\n\n public isClosed = false;\n private isQuiz = false;\n private isRetracted = false;\n private isPublic = false;\n private isMultiple = false;\n private chosenIndexes: number[] = [];\n private percents: number[];\n\n public message: Message.message;\n public managers: AppManagers;\n\n private quizInterval: number;\n private quizTimer: SVGSVGElement;\n\n private sendVoteBtn: HTMLElement;\n private chosingIndexes: number[] = [];\n\n private sendVotePromise: Promise<void>;\n private sentVote = false;\n\n private detachClickEvent: () => void;\n\n public static setMaxLength() {\n const width = windowSize.width <= 360 ? windowSize.width - 120 : mediaSizes.active.poll.width;\n this.MAX_LENGTH = width + tailLength + this.MAX_OFFSET + -13.7; // 13 - position left\n }\n\n public static resizePolls() {\n if(!this.MAX_LENGTH) return;\n const pollElements = Array.from(document.querySelectorAll('poll-element.is-voted')) as PollElement[];\n pollElements.forEach((pollElement) => {\n pollElement.svgLines.forEach((svg, idx) => {\n // void svg.getBoundingClientRect(); // reflow\n pollElement.setLineProgress(idx, 1);\n });\n });\n }\n\n public async render() {\n // браузер вызывает этот метод при добавлении элемента в документ\n // (может вызываться много раз, если элемент многократно добавляется/удаляется)\n\n if(!lineTotalLength) {\n lineTotalLength = (document.getElementById('poll-line') as any as SVGPathElement).getTotalLength();\n // console.log('line total length:', lineTotalLength);\n PollElement.setMaxLength();\n }\n\n // const {poll, results} = this.managers.appPollsManager.getPoll(pollId);\n const {poll, results} = this.message.media as MessageMedia.messageMediaPoll;\n\n /* const timestamp = Date.now() / 1000 | 0;\n if(timestamp < this.message.date) { */\n if(this.message.pFlags.is_scheduled) {\n this.classList.add('disable-hover');\n }\n\n // console.log('pollElement poll:', poll, results);\n\n let descKey: LangPackKey;\n if(poll.pFlags) {\n this.isPublic = !!poll.pFlags.public_voters;\n this.isQuiz = !!poll.pFlags.quiz;\n this.isClosed = !!poll.pFlags.closed;\n this.isMultiple = !!poll.pFlags.multiple_choice;\n\n if(this.isClosed) {\n descKey = 'Chat.Poll.Type.Closed';\n this.classList.add('is-closed');\n } else if(this.isQuiz) {\n descKey = this.isPublic ? 'Chat.Poll.Type.Quiz' : 'Chat.Poll.Type.AnonymousQuiz';\n } else {\n descKey = this.isPublic ? 'Chat.Poll.Type.Public' : 'Chat.Poll.Type.Anonymous';\n }\n }\n\n this.classList.toggle('is-multiple', this.isMultiple);\n\n const multipleSelect = this.isMultiple ? '<span class=\"poll-answer-selected tgico-check\"></span>' : '';\n const votes = poll.answers.map((answer, idx) => {\n return `\n <div class=\"poll-answer\" data-index=\"${idx}\">\n <div class=\"circle-hover\">\n <div class=\"animation-ring\"></div>\n <svg class=\"progress-ring\">\n <circle class=\"progress-ring__circle\" cx=\"13\" cy=\"13\" r=\"9\"></circle>\n </svg>\n ${multipleSelect}\n </div>\n <div class=\"poll-answer-percents\"></div>\n <div class=\"poll-answer-text\"></div>\n <svg version=\"1.1\" class=\"poll-line\" style=\"display: none;\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 485.9 35\" xml:space=\"preserve\">\n <use href=\"#poll-line\"></use>\n </svg>\n <span class=\"poll-answer-selected tgico\"></span>\n </div>\n `;\n }).join('');\n\n this.innerHTML = `\n <div class=\"poll-title\"></div>\n <div class=\"poll-desc\">\n <div class=\"poll-type\"></div>\n <div class=\"poll-avatars\"></div>\n </div>\n ${votes}`;\n\n setInnerHTML(this.firstElementChild, wrapEmojiText(poll.question));\n\n Array.from(this.querySelectorAll('.poll-answer-text')).forEach((el, idx) => {\n setInnerHTML(el, wrapEmojiText(poll.answers[idx].text));\n });\n\n this.descDiv = this.firstElementChild.nextElementSibling as HTMLElement;\n this.typeDiv = this.descDiv.firstElementChild as HTMLElement;\n this.avatarsDiv = this.descDiv.lastElementChild as HTMLElement;\n\n if(descKey) {\n this.typeDiv.append(i18n(descKey));\n }\n\n if(this.isQuiz) {\n this.classList.add('is-quiz');\n\n if(poll.close_period && poll.close_date) {\n const timeLeftDiv = document.createElement('div');\n timeLeftDiv.classList.add('poll-time');\n this.descDiv.append(timeLeftDiv);\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n // svg.setAttributeNS(null, 'viewBox', '0 0 15 15');\n svg.classList.add('poll-quiz-timer');\n\n this.quizTimer = svg;\n\n const strokeWidth = 2;\n const radius = 7;\n const circumference = 2 * Math.PI * radius;\n\n const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n circle.classList.add('poll-quiz-timer-circle');\n circle.setAttributeNS(null, 'cx', '16');\n circle.setAttributeNS(null, 'cy', '16');\n circle.setAttributeNS(null, 'r', '' + radius);\n circle.setAttributeNS(null, 'stroke-width', '' + strokeWidth);\n\n svg.append(circle);\n this.descDiv.append(svg);\n\n const period = poll.close_period * 1000;\n const closeTime = (poll.close_date - await rootScope.managers.timeManager.getServerTimeOffset()) * 1000;\n\n // console.log('closeTime:', poll.close_date, serverTimeManager.serverTimeOffset, Date.now() / 1000 | 0);\n\n // let time = Date.now();\n // let percents = (closeTime - time) / period;\n\n // timeLeftDiv.innerHTML = String((closeTime - time) / 1000 + 1 | 0).toHHMMSS();\n\n // // @ts-ignore\n // circle.style.strokeDashoffset = circumference + percents * circumference;\n // circle.style.strokeDasharray = ${circumference} ${circumference};\n\n this.quizInterval = window.setInterval(() => {\n const time = Date.now();\n const percents = (closeTime - time) / period;\n const timeLeft = (closeTime - time) / 1000 + 1 | 0;\n timeLeftDiv.textContent = toHHMMSS(timeLeft);\n\n if(timeLeft <= 5) {\n timeLeftDiv.style.color = '#ee545c';\n circle.style.stroke = '#ee545c';\n }\n // timeLeftDiv.style.visibility = 'visible';\n\n // @ts-ignore\n circle.style.strokeDashoffset = circumference + percents * circumference;\n circle.style.strokeDasharray = `${circumference} ${circumference}`;\n\n if(time >= closeTime) {\n clearInterval(this.quizInterval);\n timeLeftDiv.replaceChildren();\n // @ts-ignore\n circle.style.strokeDashoffset = circumference;\n this.quizInterval = 0;\n\n setTimeout(() => {\n // нужно запросить апдейт чтобы опрос обновился\n this.managers.appPollsManager.getResults(this.message);\n }, 3e3);\n }\n }, 1e3);\n }\n }\n\n this.answerDivs = Array.from(this.querySelectorAll('.poll-answer')) as HTMLDivElement[];\n this.svgLines = Array.from(this.querySelectorAll('.poll-line')) as SVGSVGElement[];\n this.numberDivs = Array.from(this.querySelectorAll('.poll-answer-percents')) as HTMLDivElement[];\n\n const footerDiv = document.createElement('div');\n footerDiv.classList.add('poll-footer');\n\n this.viewResults = document.createElement('div');\n this.viewResults.className = 'poll-footer-button poll-view-results hide';\n this.viewResults.append(i18n('Chat.Poll.ViewResults'));\n\n this.votersCountDiv = document.createElement('div');\n this.votersCountDiv.className = 'poll-votes-count';\n\n footerDiv.append(this.viewResults, this.votersCountDiv);\n this.append(footerDiv);\n\n this.viewResults.addEventListener('click', (e) => {\n cancelEvent(e);\n\n if(!appSidebarRight.isTabExists(AppPollResultsTab)) {\n appSidebarRight.createTab(AppPollResultsTab).open(this.message);\n }\n });\n ripple(this.viewResults);\n\n if(this.isMultiple) {\n this.sendVoteBtn = document.createElement('div');\n this.sendVoteBtn.classList.add('poll-footer-button', 'poll-send-vote');\n this.sendVoteBtn.append(i18n('Chat.Poll.SubmitVote'));\n ripple(this.sendVoteBtn);\n\n if(!poll.chosenIndexes.length) {\n this.votersCountDiv.classList.add('hide');\n }\n\n attachClickEvent(this.sendVoteBtn, (e) => {\n cancelEvent(e);\n /* const indexes = this.answerDivs.filter((el) => el.classList.contains('is-chosing')).map((el) => +el.dataset.index);\n if(indexes.length) {\n\n } */\n if(this.chosingIndexes.length) {\n this.sendVotes(this.chosingIndexes).then(() => {\n this.chosingIndexes.length = 0;\n this.answerDivs.forEach((el) => {\n el.classList.remove('is-chosing');\n });\n });\n }\n });\n\n footerDiv.append(this.sendVoteBtn);\n }\n\n // const width = this.getBoundingClientRect().width;\n // const width = mediaSizes.active.poll.width;\n // this.maxLength = width + tailLength + this.maxOffset + -13.7; // 13 - position left\n\n const canVote = !(poll.chosenIndexes.length || this.isClosed);\n if(!canVote || this.isPublic) {\n this.performResults(results, poll.chosenIndexes, false);\n }\n\n if(canVote) {\n this.setVotersCount(results);\n this.detachClickEvent = attachClickEvent(this, this.clickHandler);\n }\n }\n\n initQuizHint(results: PollResults) {\n if(results.solution && results.solution_entities) {\n const toggleHint = document.createElement('div');\n toggleHint.classList.add('tgico-tip', 'poll-hint');\n this.descDiv.append(toggleHint);\n\n // let active = false;\n attachClickEvent(toggleHint, (e) => {\n cancelEvent(e);\n\n // active = true;\n toggleHint.classList.add('active');\n setQuizHint(results.solution, results.solution_entities, () => {\n // active = false;\n toggleHint.classList.remove('active');\n });\n });\n\n if(this.sentVote) {\n const correctResult = results.results.find((r) => r.pFlags.correct);\n if(correctResult && !correctResult.pFlags.chosen) {\n simulateClickEvent(toggleHint);\n }\n }\n }\n }\n\n clickHandler = (e: Event) => {\n const target = findUpClassName(e.target, 'poll-answer') as HTMLElement;\n if(!target) {\n return;\n }\n\n cancelEvent(e);\n const answerIndex = +target.dataset.index;\n if(this.isMultiple) {\n target.classList.toggle('is-chosing');\n\n const foundIndex = this.chosingIndexes.indexOf(answerIndex);\n if(foundIndex !== -1) {\n this.chosingIndexes.splice(foundIndex, 1);\n } else {\n this.chosingIndexes.push(answerIndex);\n }\n } else {\n this.sendVotes([answerIndex]);\n }\n\n /* target.classList.add('is-voting');\n setTimeout(() => { // simulate\n this.setResults([100, 0], answerIndex);\n target.classList.remove('is-voting');\n }, 1000); */\n };\n\n sendVotes(indexes: number[]) {\n if(this.sendVotePromise) return this.sendVotePromise;\n\n const targets = this.answerDivs.filter((_, idx) => indexes.includes(idx));\n targets.forEach((target) => {\n target.classList.add('is-voting');\n });\n\n this.classList.add('disable-hover');\n this.sentVote = true;\n return this.sendVotePromise = this.managers.appPollsManager.sendVote(this.message, indexes).then(() => {\n targets.forEach((target) => {\n target.classList.remove('is-voting');\n });\n\n this.classList.remove('disable-hover');\n }).catch(() => {\n this.sentVote = false;\n }).finally(() => {\n this.sendVotePromise = null;\n });\n }\n\n performResults(results: PollResults, chosenIndexes: number[], animate = true) {\n if(!liteMode.isAvailable('animations')) {\n animate = false;\n }\n\n if(this.isQuiz && (results.results?.length || this.isClosed)) {\n this.answerDivs.forEach((el, idx) => {\n el.classList.toggle('is-correct', !!results.results[idx].pFlags.correct);\n });\n\n if(this.initQuizHint) {\n this.initQuizHint(results);\n this.initQuizHint = null;\n }\n\n if(this.quizInterval) {\n clearInterval(this.quizInterval);\n this.quizInterval = 0;\n }\n\n if(this.quizTimer?.parentElement) {\n this.quizTimer.remove();\n }\n\n const timeEl = this.descDiv.querySelector('.poll-time');\n if(timeEl) {\n timeEl.remove();\n }\n }\n\n if(this.isClosed) {\n this.classList.add('is-closed');\n replaceContent(this.typeDiv, i18n('Chat.Poll.Type.Closed'));\n }\n\n // set chosen\n if(this.chosenIndexes.length !== chosenIndexes.length || this.isClosed) { // if we voted\n this.isRetracted = this.chosenIndexes.length && !chosenIndexes.length;\n this.chosenIndexes = chosenIndexes.slice();\n\n if(this.isRetracted) {\n this.detachClickEvent = attachClickEvent(this, this.clickHandler);\n } else {\n this.detachClickEvent?.();\n this.detachClickEvent = undefined;\n }\n }\n\n // is need update\n if(this.chosenIndexes.length || this.isRetracted || this.isClosed) {\n const percents = results.results.map((v) => results.total_voters ? v.voters / results.total_voters * 100 : 0);\n\n this.classList.toggle('no-transition', !animate);\n if(animate) {\n SetTransition({\n element: this,\n className: '',\n forwards: !this.isRetracted,\n duration: 340\n });\n }\n\n fastRaf(() => {\n this.setResults(this.isRetracted ? this.percents : percents, this.chosenIndexes, animate);\n this.percents = percents;\n this.isRetracted = false;\n });\n }\n\n this.setVotersCount(results);\n\n if(this.isPublic) {\n if(!this.isMultiple) {\n this.viewResults.classList.toggle('hide', !results.total_voters || !this.chosenIndexes.length);\n this.votersCountDiv.classList.toggle('hide', !!this.chosenIndexes.length);\n }\n\n const peerIds = (results.recent_voters || []).map((userId) => userId.toPeerId());\n const stackedAvatars = new StackedAvatars({avatarSize: 16});\n stackedAvatars.render(peerIds);\n replaceContent(this.avatarsDiv, stackedAvatars.container);\n }\n\n if(this.isMultiple) {\n const isVoted = !!this.chosenIndexes.length;\n\n const hideSendVoteBtn = this.isClosed || isVoted;\n const hideViewResultsBtn = !this.isPublic || !results.total_voters || (!isVoted && !this.isClosed);\n this.sendVoteBtn.classList.toggle('hide', hideSendVoteBtn);\n this.viewResults.classList.toggle('hide', hideViewResultsBtn);\n this.votersCountDiv.classList.toggle('hide', !hideSendVoteBtn || !hideViewResultsBtn);\n }\n }\n\n setResults(percents: number[], chosenIndexes: number[], animate: boolean) {\n this.svgLines.forEach((svg) => svg.style.display = '');\n\n this.answerDivs.forEach((el, idx) => {\n el.classList.toggle('is-chosen', chosenIndexes.includes(idx));\n });\n\n const maxValue = Math.max(...percents);\n // this.maxLengths = percents.map((p) => p / maxValue * this.maxLength);\n this.maxPercents = percents.map((p) => p / maxValue);\n\n // line\n if(this.isRetracted) {\n this.svgLines.forEach((svg, idx) => {\n this.setLineProgress(idx, -1);\n });\n } else {\n const cb = () => {\n this.svgLines.forEach((svg, idx) => {\n // void svg.getBoundingClientRect(); // reflow\n this.setLineProgress(idx, 1);\n });\n };\n\n animate ? fastRaf(cb) : cb();\n }\n\n percents = percents.slice();\n roundPercents(percents);\n let getPercentValue: (percents: number, index: number) => number;\n const iterate = (i: number) => {\n percents.forEach((percents, idx) => {\n const value = getPercentValue(percents, i);\n this.numberDivs[idx].innerText = value + '%';\n });\n };\n // numbers\n if(this.isRetracted) {\n getPercentValue = (percents, index) => Math.round(percents / times * index);\n\n if(animate) {\n for(let i = (times - 1), k = 0; i >= 0; --i, ++k) {\n setTimeout(() => {\n iterate(i);\n }, oneTime * k);\n }\n } else {\n iterate(0);\n }\n } else {\n getPercentValue = (percents, index) => Math.round(percents / times * (index + 1));\n\n if(animate) {\n for(let i = 0; i < times; ++i) {\n setTimeout(() => {\n iterate(i);\n }, oneTime * i);\n }\n } else {\n iterate(times - 1);\n }\n }\n\n if(this.isRetracted) {\n if(animate) {\n this.classList.add('is-retracting');\n }\n\n this.classList.remove('is-voted');\n const cb = () => {\n this.svgLines.forEach((svg) => svg.style.display = 'none');\n };\n\n if(animate) {\n setTimeout(() => {\n this.classList.remove('is-retracting');\n cb();\n }, fullTime);\n } else {\n cb();\n }\n } else {\n this.classList.add('is-voted');\n }\n }\n\n setVotersCount(results: PollResults) {\n const votersCount = results.total_voters || 0;\n let key: LangPackKey;\n const args: FormatterArguments = [votersCount];\n if(this.isClosed) {\n if(this.isQuiz) key = votersCount ? 'Chat.Quiz.TotalVotes' : 'Chat.Quiz.TotalVotesResultEmpty';\n else key = votersCount ? 'Chat.Poll.TotalVotes1' : 'Chat.Poll.TotalVotesResultEmpty';\n } else {\n if(this.isQuiz) key = votersCount ? 'Chat.Quiz.TotalVotes' : 'Chat.Quiz.TotalVotesEmpty';\n else key = votersCount ? 'Chat.Poll.TotalVotes1' : 'Chat.Poll.TotalVotesEmpty';\n }\n\n replaceContent(this.votersCountDiv, i18n(key, args));\n }\n\n setLineProgress(index: number, multiplier: number) {\n const svg = this.svgLines[index];\n\n if(multiplier === -1) {\n svg.style.strokeDasharray = '';\n svg.style.strokeDashoffset = '';\n } else {\n // svg.style.strokeDasharray = (multiplier * this.maxLengths[index]) + ', 485.9';\n svg.style.strokeDasharray = (multiplier * this.maxPercents[index] * PollElement.MAX_LENGTH) + ', 485.9';\n // svg.style.strokeDasharray = (multiplier * this.maxPercents[index] * 100) + '%, 485.9';\n svg.style.strokeDashoffset = '' + multiplier * PollElement.MAX_OFFSET;\n }\n }\n\n // у элемента могут быть ещё другие методы и свойства\n}\n\ncustomElements.define('poll-element', PollElement);\n","// https://stackoverflow.com/a/14824756/6758968\nconst ltrChars = 'A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02B8\\u0300-\\u0590\\u0800-\\u1FFF'+'\\u2C00-\\uFB1C\\uFDFE-\\uFE6F\\uFEFD-\\uFFFF',\n rtlChars = '\\u0591-\\u07FF\\uFB1D-\\uFDFD\\uFE70-\\uFEFC',\n fullRtlDirCheck = new RegExp('^[^'+ltrChars+']*['+rtlChars+']'),\n justRtlDirCheck = new RegExp('['+rtlChars+']');\n\nexport default function isRTL(s: string, anyChar?: boolean) {\n return anyChar ? justRtlDirCheck.test(s) : fullRtlDirCheck.test(s);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {AppImManager, ChatSavedPosition, ChatSetPeerOptions} from '../../lib/appManagers/appImManager';\nimport type {HistoryResult, MyMessage} from '../../lib/appManagers/appMessagesManager';\nimport type {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport type Chat from './chat';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport {logger} from '../../lib/logger';\nimport rootScope from '../../lib/rootScope';\nimport BubbleGroups from './bubbleGroups';\nimport PopupDatePicker from '../popups/datePicker';\nimport PopupForward from '../popups/forward';\nimport PopupStickers from '../popups/stickers';\nimport ProgressivePreloader from '../preloader';\nimport Scrollable, {SliceSides} from '../scrollable';\nimport StickyIntersector from '../stickyIntersector';\nimport animationIntersector from '../animationIntersector';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport {IS_ANDROID, IS_APPLE, IS_MOBILE, IS_SAFARI} from '../../environment/userAgent';\nimport I18n, {FormatterArguments, i18n, langPack, LangPackKey, UNSUPPORTED_LANG_PACK_KEY, _i18n} from '../../lib/langPack';\nimport AvatarElement from '../avatar';\nimport ripple from '../ripple';\nimport {MessageRender} from './messageRender';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport PollElement from '../poll';\nimport AudioElement from '../audio';\nimport {ChannelParticipant, Chat as MTChat, ChatInvite, ChatParticipant, Document, Message, MessageEntity, MessageMedia, MessageReplyHeader, Photo, PhotoSize, ReactionCount, ReplyMarkup, SponsoredMessage, Update, UrlAuthResult, User, WebPage} from '../../layer';\nimport {BOT_START_PARAM, NULL_PEER_ID, REPLIES_PEER_ID} from '../../lib/mtproto/mtproto_config';\nimport {FocusDirection, ScrollStartCallbackDimensions} from '../../helpers/fastSmoothScroll';\nimport useHeavyAnimationCheck, {getHeavyAnimationPromise, dispatchHeavyAnimationEvent, interruptHeavyAnimation} from '../../hooks/useHeavyAnimationCheck';\nimport {fastRaf, fastRafPromise} from '../../helpers/schedulers';\nimport deferredPromise from '../../helpers/cancellablePromise';\nimport RepliesElement from './replies';\nimport DEBUG from '../../config/debug';\nimport {SliceEnd} from '../../helpers/slicedArray';\nimport PeerTitle from '../peerTitle';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport findUpTag from '../../helpers/dom/findUpTag';\nimport {toast, toastNew} from '../toast';\nimport {getMiddleware, Middleware} from '../../helpers/middleware';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport {attachClickEvent, simulateClickEvent} from '../../helpers/dom/clickEvent';\nimport htmlToDocumentFragment from '../../helpers/dom/htmlToDocumentFragment';\nimport reflowScrollableElement from '../../helpers/dom/reflowScrollableElement';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport whichChild from '../../helpers/dom/whichChild';\nimport {cancelAnimationByKey} from '../../helpers/animation';\nimport assumeType from '../../helpers/assumeType';\nimport debounce, {DebounceReturnType} from '../../helpers/schedulers/debounce';\nimport {SEND_WHEN_ONLINE_TIMESTAMP} from '../../lib/mtproto/constants';\nimport windowSize from '../../helpers/windowSize';\nimport {formatPhoneNumber} from '../../helpers/formatPhoneNumber';\nimport AppMediaViewer from '../appMediaViewer';\nimport SetTransition from '../singleTransition';\nimport handleHorizontalSwipe from '../../helpers/dom/handleHorizontalSwipe';\nimport findUpAttribute from '../../helpers/dom/findUpAttribute';\nimport findUpAsChild from '../../helpers/dom/findUpAsChild';\nimport formatCallDuration from '../../helpers/formatCallDuration';\nimport IS_CALL_SUPPORTED from '../../environment/callSupport';\nimport Button from '../button';\nimport {CallType} from '../../lib/calls/types';\nimport getVisibleRect from '../../helpers/dom/getVisibleRect';\nimport PopupJoinChatInvite from '../popups/joinChatInvite';\nimport {InternalLink, INTERNAL_LINK_TYPE} from '../../lib/appManagers/internalLink';\nimport ReactionsElement, {REACTIONS_ELEMENTS} from './reactions';\nimport type ReactionElement from './reaction';\nimport RLottiePlayer from '../../lib/rlottie/rlottiePlayer';\nimport pause from '../../helpers/schedulers/pause';\nimport ScrollSaver from '../../helpers/scrollSaver';\nimport getObjectKeysAndSort from '../../helpers/object/getObjectKeysAndSort';\nimport forEachReverse from '../../helpers/array/forEachReverse';\nimport formatNumber from '../../helpers/number/formatNumber';\nimport getViewportSlice from '../../helpers/dom/getViewportSlice';\nimport SuperIntersectionObserver from '../../helpers/dom/superIntersectionObserver';\nimport generateFakeIcon from '../generateFakeIcon';\nimport copyFromElement from '../../helpers/dom/copyFromElement';\nimport PopupElement from '../popups';\nimport setAttachmentSize from '../../helpers/setAttachmentSize';\nimport wrapWebPageDescription from '../wrappers/webPageDescription';\nimport wrapWebPageTitle from '../wrappers/webPageTitle';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport wrapRichText from '../../lib/richTextProcessor/wrapRichText';\nimport wrapMessageActionTextNew from '../wrappers/messageActionTextNew';\nimport isMentionUnread from '../../lib/appManagers/utils/messages/isMentionUnread';\nimport getMediaFromMessage from '../../lib/appManagers/utils/messages/getMediaFromMessage';\nimport getPeerColorById from '../../lib/appManagers/utils/peers/getPeerColorById';\nimport getPeerId from '../../lib/appManagers/utils/peers/getPeerId';\nimport getServerMessageId from '../../lib/appManagers/utils/messageId/getServerMessageId';\nimport generateMessageId from '../../lib/appManagers/utils/messageId/generateMessageId';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport {Awaited, SendMessageEmojiInteractionData} from '../../types';\nimport idleController from '../../helpers/idleController';\nimport overlayCounter from '../../helpers/overlayCounter';\nimport {cancelContextMenuOpening} from '../../helpers/dom/attachContextMenuListener';\nimport contextMenuController from '../../helpers/contextMenuController';\nimport {AckedResult} from '../../lib/mtproto/superMessagePort';\nimport middlewarePromise from '../../helpers/middlewarePromise';\nimport {EmoticonsDropdown} from '../emoticonsDropdown';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport noop from '../../helpers/noop';\nimport getAlbumText from '../../lib/appManagers/utils/messages/getAlbumText';\nimport paymentsWrapCurrencyAmount from '../../helpers/paymentsWrapCurrencyAmount';\nimport PopupPayment from '../popups/payment';\nimport isInDOM from '../../helpers/dom/isInDOM';\nimport getStickerEffectThumb from '../../lib/appManagers/utils/stickers/getStickerEffectThumb';\nimport attachStickerViewerListeners from '../stickerViewer';\nimport {makeMediaSize, MediaSize} from '../../helpers/mediaSize';\nimport wrapSticker, {onEmojiStickerClick} from '../wrappers/sticker';\nimport wrapAlbum from '../wrappers/album';\nimport wrapDocument from '../wrappers/document';\nimport wrapGroupedDocuments from '../wrappers/groupedDocuments';\nimport wrapPhoto from '../wrappers/photo';\nimport wrapPoll from '../wrappers/poll';\nimport wrapVideo from '../wrappers/video';\nimport isRTL from '../../helpers/string/isRTL';\nimport NBSP from '../../helpers/string/nbsp';\nimport DotRenderer from '../dotRenderer';\nimport toHHMMSS from '../../helpers/string/toHHMMSS';\nimport {BatchProcessor} from '../../helpers/sortedList';\nimport wrapUrl from '../../lib/richTextProcessor/wrapUrl';\nimport getMessageThreadId from '../../lib/appManagers/utils/messages/getMessageThreadId';\nimport wrapTopicNameButton from '../wrappers/topicNameButton';\nimport wrapMediaSpoiler, {onMediaSpoilerClick, toggleMediaSpoiler} from '../wrappers/mediaSpoiler';\nimport toggleDisability from '../../helpers/dom/toggleDisability';\nimport {copyTextToClipboard} from '../../helpers/clipboard';\nimport liteMode from '../../helpers/liteMode';\nimport getMediaDurationFromMessage from '../../lib/appManagers/utils/messages/getMediaDurationFromMessage';\nimport wrapLocalSticker from '../wrappers/localSticker';\nimport {LottieAssetName} from '../../lib/rlottie/lottieLoader';\nimport clamp from '../../helpers/number/clamp';\nimport getParticipantRank from '../../lib/appManagers/utils/chats/getParticipantRank';\nimport wrapParticipantRank from '../wrappers/participantRank';\n\nexport const USER_REACTIONS_INLINE = false;\nconst USE_MEDIA_TAILS = false;\ntype MESSAGE_ACTION_TYPE = Message.messageService['action']['_'];\ntype IGNORE_ACTION_KEY = MESSAGE_ACTION_TYPE;\ntype IGNORE_ACTION_VALUE = true | ((message: Message.messageService) => boolean);\nconst IGNORE_ACTIONS: Map<IGNORE_ACTION_KEY, IGNORE_ACTION_VALUE> = new Map([\n ['messageActionHistoryClear', true],\n ['messageActionChatCreate', (message) => message.pFlags.out]\n // 'messageActionChannelMigrateFrom'\n] as [IGNORE_ACTION_KEY, IGNORE_ACTION_VALUE][]);\n\nexport const SERVICE_AS_REGULAR: Set<MESSAGE_ACTION_TYPE> = new Set();\n\nif(IS_CALL_SUPPORTED) {\n SERVICE_AS_REGULAR.add('messageActionPhoneCall');\n}\n\nconst TEST_SCROLL_TIMES: number = undefined;\nlet TEST_SCROLL = TEST_SCROLL_TIMES;\n\nlet queueId = 0;\n\ntype GenerateLocalMessageType<IsService> = IsService extends true ? Message.messageService : Message.message;\n\nconst SPONSORED_MESSAGE_ID_OFFSET = 1;\nexport const STICKY_OFFSET = 3;\nconst SCROLLED_DOWN_THRESHOLD = 300;\nconst PEER_CHANGED_ERROR = new Error('peer changed');\n\nconst DO_NOT_SLICE_VIEWPORT = false;\nconst DO_NOT_SLICE_VIEWPORT_ON_RENDER = false;\nconst DO_NOT_UPDATE_MESSAGE_VIEWS = false;\nconst DO_NOT_UPDATE_MESSAGE_REACTIONS = false;\nconst DO_NOT_UPDATE_MESSAGE_REPLY = false;\n\nconst BIG_EMOJI_SIZES: {[size: number]: number} = {\n 1: 96,\n 2: 90,\n 3: 84,\n 4: 72,\n 5: 60,\n 6: 48,\n 7: 36\n};\nconst BIG_EMOJI_SIZES_LENGTH = Object.keys(BIG_EMOJI_SIZES).length;\n\ntype Bubble = {\n bubble: HTMLElement,\n mids: Set<number>,\n groupedId?: string\n};\n\ntype MyHistoryResult = HistoryResult | {history: number[]};\n\nfunction getMainMidForGrouped(mids: number[]) {\n return Math.max(...mids);\n}\n\nexport default class ChatBubbles {\n public container: HTMLDivElement;\n public chatInner: HTMLDivElement;\n public scrollable: Scrollable;\n\n private getHistoryTopPromise: Promise<boolean>;\n private getHistoryBottomPromise: Promise<boolean>;\n\n // public messagesCount: number = -1;\n\n private unreadOut = new Set<number>();\n public needUpdate: {replyToPeerId: PeerId, replyMid: number, mid: number}[] = []; // if need wrapSingleMessage\n\n public bubbles: {[mid: string]: HTMLElement} = {};\n public skippedMids: Set<number> = new Set();\n public bubblesNewByGroupedId: {[groupId: string]: Bubble} = {};\n public bubblesNew: {[mid: string]: Bubble} = {};\n private dateMessages: {[timestamp: number]: {\n div: HTMLElement,\n firstTimestamp: number,\n container: HTMLElement,\n timeout?: number\n }} = {};\n\n private scrolledDown = true;\n private isScrollingTimeout = 0;\n\n private stickyIntersector: StickyIntersector;\n\n private unreaded: Map<HTMLElement, number> = new Map();\n private unreadedSeen: Set<number> = new Set();\n private readPromise: Promise<void>;\n\n private bubbleGroups: BubbleGroups;\n\n private preloader: ProgressivePreloader = null;\n\n // private messagesQueueOnRender: () => void = null;\n private messagesQueueOnRenderAdditional: () => void = null;\n\n private firstUnreadBubble: HTMLElement = null;\n private attachedUnreadBubble: boolean;\n\n public lazyLoadQueue: LazyLoadQueue;\n\n private middlewareHelper = getMiddleware();\n\n private log: ReturnType<typeof logger>;\n\n public listenerSetter: ListenerSetter;\n\n private followStack: number[] = [];\n\n private isHeavyAnimationInProgress = false;\n private scrollingToBubble: HTMLElement;\n\n private isFirstLoad = true;\n private needReflowScroll: boolean;\n\n private fetchNewPromise: Promise<void>;\n\n private passEntities: Partial<{\n [_ in MessageEntity['_']]: boolean\n }> = {};\n\n private onAnimateLadder: () => Promise<any> | void;\n // private ladderDeferred: CancellablePromise<void>;\n private resolveLadderAnimation: () => Promise<any>;\n private emptyPlaceholderBubble: HTMLElement;\n\n private viewsMids: Set<number> = new Set();\n private sendViewCountersDebounced: () => Promise<void>;\n\n private isTopPaddingSet = false;\n\n private getSponsoredMessagePromise: Promise<void>;\n\n private previousStickyDate: HTMLElement;\n private sponsoredMessage: SponsoredMessage.sponsoredMessage;\n\n private hoverBubble: HTMLElement;\n private hoverReaction: HTMLElement;\n private sliceViewportDebounced: DebounceReturnType<ChatBubbles['sliceViewport']>;\n private resizeObserver: ResizeObserver;\n private willScrollOnLoad: boolean;\n public observer: SuperIntersectionObserver;\n\n private renderingMessages: Set<number> = new Set();\n private setPeerCached: boolean;\n private attachPlaceholderOnRender: () => void;\n\n private bubblesToEject: Set<HTMLElement> = new Set();\n private bubblesToReplace: Map<HTMLElement, HTMLElement> = new Map(); // TO -> FROM\n private updatePlaceholderPosition: () => void;\n private setPeerOptions: {lastMsgId: number; topMessage: number; savedPosition: ChatSavedPosition};\n\n private setPeerTempId: number = 0;\n\n private renderNewPromises: Set<Promise<any>> = new Set();\n private updateGradient: boolean;\n\n private extendedMediaMessages: Set<number> = new Set();\n private pollExtendedMediaMessagesPromise: Promise<void>;\n\n private batchProcessor: BatchProcessor<Awaited<ReturnType<ChatBubbles['safeRenderMessage']>>>;\n\n private ranks: Map<PeerId, ReturnType<typeof getParticipantRank>>;\n private processRanks: Set<() => void>;\n private canShowRanks: boolean;\n // private reactions: Map<number, ReactionsElement>;\n\n constructor(\n private chat: Chat,\n private managers: AppManagers\n ) {\n this.log = this.chat.log;\n // this.chat.log.error('Bubbles construction');\n\n this.listenerSetter = new ListenerSetter();\n\n this.constructBubbles();\n\n // * constructor end\n\n this.batchProcessor = new BatchProcessor({\n log: this.log,\n process: this.processBatch,\n possibleError: PEER_CHANGED_ERROR\n });\n this.bubbleGroups = new BubbleGroups(this.chat);\n this.preloader = new ProgressivePreloader({\n cancelable: false\n });\n this.lazyLoadQueue = new LazyLoadQueue(undefined, true);\n this.lazyLoadQueue.queueId = ++queueId;\n\n // this.reactions = new Map();\n\n // * events\n\n // will call when sent for update pos\n this.listenerSetter.add(rootScope)('history_update', async({storageKey, sequential, message}) => {\n if(this.chat.messagesStorageKey !== storageKey || this.chat.type === 'scheduled') {\n return;\n }\n\n const {mid} = message;\n const log = false ? this.log.bindPrefix('history_update-' + mid) : undefined;\n log && log('start');\n\n const bubble = this.bubbles[mid];\n if(!bubble) return;\n\n if(this.renderNewPromises.size) {\n log && log.error('will await new messages render');\n await Promise.all(Array.from(this.renderNewPromises));\n }\n\n if(this.messagesQueuePromise) {\n log && log.error('messages render in process');\n await this.messagesQueuePromise;\n }\n\n if(this.bubbles[mid] !== bubble) return;\n\n // await getHeavyAnimationPromise();\n\n const item = this.bubbleGroups.getItemByBubble(bubble);\n if(!item) { // probably a group item\n log && log.error('no item by bubble', bubble);\n return;\n } else if(item.mid === mid) {\n log && log.warn('wow what', item, mid);\n return;\n }\n\n if(sequential) {\n const group = item.group;\n const newItem = this.bubbleGroups.createItem(bubble, message);\n // newItem.mid = item.mid;\n const _items = this.bubbleGroups.itemsArr.slice();\n indexOfAndSplice(_items, item);\n const foundItem = this.bubbleGroups.findGroupSiblingByItem(newItem, _items);\n if(\n group === foundItem?.group ||\n (group === this.bubbleGroups.getLastGroup() && group.items.length === 1 && newItem.dateTimestamp === item.dateTimestamp) ||\n (this.peerId === rootScope.myId && sequential && newItem.dateTimestamp === item.dateTimestamp)\n ) {\n log && log('item has correct position', item);\n this.bubbleGroups.changeBubbleMid(bubble, mid);\n return;\n }\n }\n\n // return;\n\n // await fastRafPromise();\n // if(this.bubbles[mid] !== bubble) return;\n\n // const groupIndex = this.bubbleGroups.groups.indexOf(group);\n this.bubbleGroups.removeAndUnmountBubble(bubble);\n // if(!group.items.length) { // group has collapsed, next message can have higher mid so have to reposition them too\n // log && log('group has collapsed', item);\n\n // const siblingGroups = this.bubbleGroups.groups.slice(0, groupIndex + 1);\n // for(let length = siblingGroups.length, i = length - 2; i >= 0; --i) {\n // const siblingGroup = siblingGroups[i];\n // const siblingItems = siblingGroup.items;\n // const nextGroup = siblingGroups[i + 1];\n // const nextItems = nextGroup.items;\n\n // let _break = false, moved = false;\n // for(let j = siblingItems.length - 1; j >= 0; --j) {\n // const siblingItem = siblingItems[j];\n // const foundItem = this.bubbleGroups.findGroupSiblingByItem(siblingItem, nextItems);\n // if(!foundItem) {\n // _break = true;\n // break;\n // }\n\n // log('will move item', siblingItem, nextGroup);\n // this.bubbleGroups.removeAndUnmountBubble(siblingItem.bubble);\n // this.bubbleGroups.addItemToGroup(siblingItem, nextGroup);\n // moved = true;\n // }\n\n // if(moved) {\n // nextGroup.mount();\n // }\n\n // if(_break) {\n // break;\n // }\n // }\n // }\n\n const {groups} = this.groupBubbles([{bubble, message}]);\n this.bubbleGroups.mountUnmountGroups(groups);\n\n if(this.scrollingToBubble) {\n this.scrollToEnd();\n }\n\n log && log('end');\n\n // this.bubbleGroups.findIncorrentPositions();\n });\n\n this.listenerSetter.add(rootScope)('dialog_flush', ({peerId}) => {\n if(this.peerId === peerId) {\n this.deleteMessagesByIds(Object.keys(this.bubbles).map((m) => +m));\n }\n });\n\n // Calls when message successfully sent and we have an id\n this.listenerSetter.add(rootScope)('message_sent', async(e) => {\n const {storageKey, tempId, tempMessage, mid, message} = e;\n\n // ! can't use peerId to validate here, because id can be the same in 'scheduled' and 'chat' types\n if(this.chat.messagesStorageKey !== storageKey) {\n return;\n }\n\n const bubbles = this.bubbles;\n const _bubble = bubbles[tempId];\n if(_bubble) {\n const bubble = bubbles[tempId];\n bubbles[mid] = bubble;\n bubble.dataset.mid = '' + mid;\n delete bubbles[tempId];\n\n fastRaf(() => {\n const mid = +bubble.dataset.mid;\n if(bubbles[mid] === bubble && bubble.classList.contains('is-outgoing')) {\n bubble.classList.remove('is-sending', 'is-outgoing');\n bubble.classList.add((this.peerId === rootScope.myId && this.chat.type !== 'scheduled') || !this.unreadOut.has(mid) ? 'is-read' : 'is-sent');\n }\n });\n }\n\n if(this.unreadOut.has(tempId)) {\n this.unreadOut.delete(tempId);\n this.unreadOut.add(mid);\n }\n\n // * check timing of scheduled message\n if(this.chat.type === 'scheduled') {\n const timestamp = Date.now() / 1000 | 0;\n const maxTimestamp = tempMessage.date - 10;\n if(timestamp >= maxTimestamp) {\n this.deleteMessagesByIds([mid]);\n }\n }\n\n if(!_bubble) {\n return;\n }\n\n let messages: (Message.message | Message.messageService)[], tempIds: number[];\n const groupedId = (message as Message.message).grouped_id;\n if(groupedId) {\n messages = await this.managers.appMessagesManager.getMessagesByAlbum(groupedId);\n const mids = messages.map(({mid}) => mid);\n if(!mids.length || getMainMidForGrouped(mids) !== mid || bubbles[mid] !== _bubble) {\n return;\n }\n\n if(bubbles[mid] !== _bubble) {\n return;\n }\n\n tempIds = (Array.from(_bubble.querySelectorAll('.grouped-item')) as HTMLElement[]).map((el) => +el.dataset.mid);\n } else {\n messages = [message];\n tempIds = [tempId];\n }\n\n const reactionsElements = Array.from(_bubble.querySelectorAll('reactions-element')) as ReactionsElement[];\n if(reactionsElements.length) {\n reactionsElements.forEach((reactionsElement) => {\n reactionsElement.changeMessage(message as Message.message);\n });\n }\n\n (messages as Message.message[]).forEach((message, idx) => {\n if(!message) {\n return;\n }\n\n const tempId = tempIds[idx];\n const mid = message.mid;\n const bubble: HTMLElement = _bubble.querySelector(`.document-container[data-mid=\"${mid}\"]`) || _bubble;\n\n if(message._ !== 'message') {\n return;\n }\n\n if(message.replies) {\n const repliesElement = _bubble.querySelector('replies-element') as RepliesElement;\n if(repliesElement) {\n repliesElement.message = message;\n repliesElement.init();\n }\n }\n\n const media = message.media ?? {} as MessageMedia.messageMediaEmpty;\n const doc = (media as MessageMedia.messageMediaDocument).document as Document.document;\n const poll = (media as MessageMedia.messageMediaPoll).poll;\n const webPage = (media as MessageMedia.messageMediaWebPage).webpage as WebPage.webPage;\n if(doc) {\n const div = bubble.querySelector(`.document-container[data-mid=\"${tempId}\"] .document`);\n if(div) {\n const container = findUpClassName(div, 'document-container');\n\n if(!tempMessage.media?.document?.thumbs?.length && doc.thumbs?.length) {\n getHeavyAnimationPromise().then(async() => {\n const timeSpan = div.querySelector('.time');\n const newDiv = await wrapDocument({message, fontSize: rootScope.settings.messagesTextSize});\n div.replaceWith(newDiv);\n\n if(timeSpan) {\n (newDiv.querySelector('.document') || newDiv).append(timeSpan);\n }\n });\n }\n\n if(container) {\n container.dataset.mid = '' + mid;\n }\n }\n\n const element = bubble.querySelector(`audio-element[data-mid=\"${tempId}\"], .document[data-doc-id=\"${tempId}\"], .media-round[data-mid=\"${tempId}\"]`) as HTMLElement;\n if(element) {\n if(element instanceof AudioElement || element.classList.contains('media-round')) {\n element.dataset.mid = '' + message.mid;\n delete element.dataset.isOutgoing;\n (element as AudioElement).message = message;\n (element as AudioElement).onLoad(true);\n } else {\n element.dataset.docId = '' + doc.id;\n (element as any).doc = doc;\n }\n }\n } else if(poll) {\n const pollElement = bubble.querySelector('poll-element') as PollElement;\n if(pollElement) {\n pollElement.message = message;\n pollElement.setAttribute('poll-id', '' + poll.id);\n pollElement.setAttribute('message-id', '' + mid);\n }\n } else if(webPage && !bubble.querySelector('.web')) {\n getHeavyAnimationPromise().then(() => {\n this.safeRenderMessage(message, true, bubble);\n this.scrollToBubbleIfLast(bubble);\n });\n }\n\n // set new mids to album items for mediaViewer\n if(groupedId) {\n const item = (bubble.querySelector(`.grouped-item[data-mid=\"${tempId}\"]`) as HTMLElement) || bubble; // * it can be .document-container\n if(item) {\n item.dataset.mid = '' + mid;\n }\n }\n });\n });\n\n this.listenerSetter.add(rootScope)('message_edit', async({storageKey, message}) => {\n if(storageKey !== this.chat.messagesStorageKey) return;\n\n const bubble = this.bubbles[message.mid];\n if(!bubble) return;\n\n await getHeavyAnimationPromise();\n if(this.bubbles[message.mid] !== bubble) return;\n\n this.safeRenderMessage(message, true, bubble);\n });\n\n this.listenerSetter.add(rootScope)('message_error', async({storageKey, tempId}) => {\n if(storageKey !== this.chat.messagesStorageKey) return;\n\n const bubble = this.bubbles[tempId];\n if(!bubble) return;\n\n await getHeavyAnimationPromise();\n if(this.bubbles[tempId] !== bubble) return;\n\n bubble.classList.remove('is-outgoing');\n bubble.classList.add('is-error');\n });\n\n this.listenerSetter.add(rootScope)('message_transcribed', ({peerId, mid, text, pending}) => {\n if(peerId !== this.peerId) return;\n\n const bubble = this.bubbles[mid];\n if(!bubble) return;\n\n // TODO: Move it to AudioElement method `finishVoiceTranscription`\n const audioElement = bubble.querySelector('audio-element') as AudioElement;\n if(!audioElement) {\n return;\n }\n\n // const scrollSaver = this.createScrollSaver(false);\n // scrollSaver.save();\n\n const speechTextDiv = bubble.querySelector('.document-wrapper, .quote-text.has-document') as HTMLElement;\n const speechRecognitionIcon = audioElement.querySelector('.audio-to-text-button span');\n const speechRecognitionLoader = audioElement.querySelector('.loader');\n if(speechTextDiv && speechRecognitionIcon) {\n let transcribedText = speechTextDiv.querySelector('.audio-transcribed-text');\n if(!transcribedText) {\n transcribedText = document.createElement('div');\n transcribedText.classList.add('audio-transcribed-text');\n transcribedText.append(document.createTextNode(''));\n\n if(speechTextDiv.classList.contains('document-wrapper')) {\n audioElement.before(transcribedText);\n } else {\n speechTextDiv.append(transcribedText);\n }\n\n if(pending) {\n const dots = document.createElement('span');\n dots.classList.add('audio-transcribing-dots');\n transcribedText.append(dots);\n }\n } else if(!pending) {\n const dots = transcribedText.querySelector('.audio-transcribing-dots');\n dots?.remove();\n }\n\n if(!text && !pending/* && !transcribedText.classList.contains('has-some-text') */) {\n transcribedText.replaceChildren(i18n('Chat.Voice.Transribe.Error'));\n transcribedText.classList.add('is-error');\n } else if(text) {\n // transcribedText.classList.add('has-some-text');\n transcribedText.firstChild.textContent = text;\n }\n\n speechRecognitionIcon.classList.remove('tgico-transcribe');\n speechRecognitionIcon.classList.add('tgico-up');\n\n if(!pending && speechRecognitionLoader) {\n speechRecognitionLoader.classList.remove('active');\n setTimeout(() => {\n speechRecognitionLoader.remove();\n }, 300);\n }\n\n audioElement.transcriptionState = 2;\n }\n\n // scrollSaver.restore();\n });\n\n this.listenerSetter.add(rootScope)('album_edit', ({peerId, messages, deletedMids}) => {\n if(peerId !== this.peerId) return;\n\n const mids = messages.map(({mid}) => mid);\n const oldMids = mids.concat(Array.from(deletedMids));\n const wasMainMid = getMainMidForGrouped(oldMids);\n const bubble = this.bubbles[wasMainMid];\n if(!bubble) {\n return;\n }\n\n const mainMid = getMainMidForGrouped(mids);\n const message = messages.find((message) => message.mid === mainMid);\n this.safeRenderMessage(message, true, bubble);\n });\n\n // this.listenerSetter.add(rootScope)('peer_title_edit', async(peerId) => {\n // if(peerId.isUser()) {\n // const middleware = this.getMiddleware();\n // const user = await this.managers.appUsersManager.getUser(peerId.toUserId());\n // if(!middleware()) return;\n\n // const isPremium = user?.pFlags?.premium;\n // const groups = this.bubbleGroups.groups.filter((group) => group.avatar?.peerId === peerId);\n // groups.forEach((group) => {\n // group.avatar.classList.toggle('is-premium', isPremium);\n // group.avatar.classList.toggle('tgico-star', isPremium);\n // });\n // }\n // });\n\n if(!DO_NOT_UPDATE_MESSAGE_REACTIONS/* && false */) {\n this.listenerSetter.add(rootScope)('messages_reactions', async(arr) => {\n if(this.chat.type === 'scheduled') {\n return;\n }\n\n let scrollSaver: ScrollSaver;\n\n const a = arr.map(async({message, changedResults}) => {\n if(this.peerId !== message.peerId) {\n return;\n }\n\n const result = await this.getMountedBubble(message.mid, message);\n if(!result) {\n return;\n }\n\n // can be .document-container\n return {bubble: findUpClassName(result.bubble, 'bubble'), message, changedResults};\n });\n\n let top: number;\n (await Promise.all(a)).filter(Boolean).forEach(({bubble, message, changedResults}) => {\n if(!scrollSaver) {\n scrollSaver = this.createScrollSaver(false);\n scrollSaver.save();\n }\n\n const key = message.peerId + '_' + message.mid;\n const set = REACTIONS_ELEMENTS.get(key);\n if(set) {\n for(const element of set) {\n element.update(message, changedResults);\n }\n } else if(!message.reactions || !message.reactions.results.length) {\n return;\n } else {\n this.appendReactionsElementToBubble(bubble, message, message, changedResults);\n }\n });\n\n if(scrollSaver) {\n scrollSaver.restore();\n }\n });\n }\n\n !DO_NOT_UPDATE_MESSAGE_REPLY && this.listenerSetter.add(rootScope)('messages_downloaded', async({peerId, mids}) => {\n const middleware = this.getMiddleware();\n await getHeavyAnimationPromise();\n if(!middleware()) return;\n\n (mids as number[]).forEach((mid) => {\n const needUpdate = this.needUpdate;\n const filtered: typeof needUpdate[0][] = [];\n forEachReverse(this.needUpdate, (obj, idx) => {\n if(obj.replyMid === mid && obj.replyToPeerId === peerId) {\n this.needUpdate.splice(idx, 1)[0];\n filtered.push(obj);\n }\n });\n\n filtered.forEach(async({mid, replyMid, replyToPeerId}) => {\n const bubble = this.bubbles[mid];\n if(!bubble) return;\n\n const [message, originalMessage] = await Promise.all([\n (await this.chat.getMessage(mid)) as Message.message,\n (await this.managers.appMessagesManager.getMessageByPeer(replyToPeerId, replyMid)) as Message.message\n ]);\n if(!middleware()) return;\n\n MessageRender.setReply({\n chat: this.chat,\n bubble,\n message\n });\n\n let maxMediaTimestamp: number;\n const timestamps = bubble.querySelectorAll<HTMLAnchorElement>('.timestamp');\n if(originalMessage && (maxMediaTimestamp = getMediaDurationFromMessage(originalMessage))) {\n timestamps.forEach((timestamp) => {\n const value = +timestamp.dataset.timestamp;\n if(value < maxMediaTimestamp) {\n timestamp.classList.remove('is-disabled');\n } else {\n timestamp.removeAttribute('href');\n }\n });\n }\n });\n });\n });\n\n attachStickerViewerListeners({\n listenTo: this.scrollable.container,\n listenerSetter: this.listenerSetter,\n findTarget: (e) => {\n const target = e.target as HTMLElement;\n const found = target.closest('.attachment.media-sticker-wrapper') || (findUpClassName(target, 'attachment') && target.closest('.custom-emoji'));\n return found as HTMLElement;\n }\n });\n attachClickEvent(this.scrollable.container, this.onBubblesClick, {listenerSetter: this.listenerSetter});\n // this.listenerSetter.add(this.bubblesContainer)('click', this.onBubblesClick/* , {capture: true, passive: false} */);\n\n this.listenerSetter.add(this.scrollable.container)('mousedown', (e) => {\n if(e.button !== 0) return;\n\n const code: HTMLElement = findUpTag(e.target, 'CODE');\n if(code) {\n cancelEvent(e);\n copyFromElement(code);\n\n const onClick = (e: MouseEvent) => {\n cancelEvent(e);\n toastNew({\n langPackKey: 'TextCopied',\n onClose: () => {\n detach();\n }\n });\n };\n\n const detach = attachClickEvent(window, onClick, {listenerSetter: this.listenerSetter, once: true, capture: true});\n return;\n }\n });\n\n /* if(false) */this.stickyIntersector = new StickyIntersector(this.scrollable.container, (stuck, target) => {\n for(const timestamp in this.dateMessages) {\n const dateMessage = this.dateMessages[timestamp];\n if(dateMessage.container === target) {\n const dateBubble = dateMessage.div;\n\n // dateMessage.container.classList.add('has-sticky-dates');\n\n // SetTransition(dateBubble, 'kek', stuck, this.previousStickyDate ? 300 : 0);\n // if(this.previousStickyDate) {\n // dateBubble.classList.add('kek');\n // }\n\n dateBubble.classList.toggle('is-sticky', stuck);\n if(stuck) {\n this.previousStickyDate = dateBubble;\n }\n\n break;\n }\n }\n\n if(this.previousStickyDate) {\n // fastRaf(() => {\n // this.bubblesContainer.classList.add('has-sticky-dates');\n // });\n }\n });\n\n if(!IS_SAFARI) {\n this.sliceViewportDebounced = debounce(this.sliceViewport.bind(this), 3000, false, true);\n }\n\n let middleware: ReturnType<ChatBubbles['getMiddleware']>;\n useHeavyAnimationCheck(() => {\n this.isHeavyAnimationInProgress = true;\n this.lazyLoadQueue.lock();\n middleware = this.getMiddleware();\n\n // if(this.sliceViewportDebounced) {\n // this.sliceViewportDebounced.clearTimeout();\n // }\n }, () => {\n this.isHeavyAnimationInProgress = false;\n\n if(middleware?.()) {\n this.lazyLoadQueue.unlockAndRefresh();\n\n // if(this.sliceViewportDebounced) {\n // this.sliceViewportDebounced();\n // }\n }\n\n middleware = null;\n }, this.listenerSetter);\n }\n\n private constructBubbles() {\n const container = this.container = document.createElement('div');\n container.classList.add('bubbles', 'scrolled-down');\n\n const chatInner = this.chatInner = document.createElement('div');\n chatInner.classList.add('bubbles-inner');\n\n this.setScroll();\n\n container.append(this.scrollable.container);\n }\n\n public attachContainerListeners() {\n const container = this.container;\n\n this.chat.contextMenu.attachTo(container);\n this.chat.selection.attachListeners(container, new ListenerSetter());\n\n if(DEBUG) {\n this.listenerSetter.add(container)('dblclick', async(e) => {\n const bubble = findUpClassName(e.target, 'grouped-item') || findUpClassName(e.target, 'bubble');\n if(bubble) {\n const mid = +bubble.dataset.mid\n this.log('debug message:', await this.chat.getMessage(mid));\n this.highlightBubble(bubble);\n }\n });\n }\n\n if(!IS_MOBILE) {\n this.listenerSetter.add(container)('dblclick', async(e) => {\n if(this.chat.type === 'pinned' ||\n this.chat.selection.isSelecting ||\n !(await this.chat.canSend())) {\n return;\n }\n\n const target = e.target as HTMLElement;\n const bubble = target.classList.contains('bubble') ?\n target :\n (target.classList.contains('document-selection') ? target.parentElement : null);\n if(bubble && !bubble.classList.contains('bubble-first')) {\n const mid = +bubble.dataset.mid;\n const message = await this.chat.getMessage(mid);\n if(message.pFlags.is_outgoing) {\n return;\n }\n\n this.chat.input.initMessageReply(mid);\n }\n });\n } else if(IS_TOUCH_SUPPORTED) {\n const className = 'is-gesturing-reply';\n const MAX = 64;\n const replyAfter = MAX * .75;\n let shouldReply = false;\n let target: HTMLElement;\n let icon: HTMLElement;\n let swipeAvatar: HTMLElement;\n handleHorizontalSwipe({\n element: container,\n verifyTouchTarget: async(e) => {\n if(this.chat.type === 'pinned' || this.chat.selection.isSelecting || !(await this.chat.canSend())) {\n return false;\n }\n\n // cancelEvent(e);\n target = findUpClassName(e.target, 'bubble');\n if(target) {\n try {\n const avatar = target.parentElement.querySelector('.bubbles-group-avatar') as HTMLElement\n if(avatar) {\n const visibleRect = getVisibleRect(avatar, target);\n if(visibleRect) {\n swipeAvatar = avatar;\n }\n }\n } catch(err) {}\n\n [target, swipeAvatar].filter(Boolean).forEach((element) => {\n SetTransition({\n element,\n className,\n forwards: true,\n duration: 250\n });\n void element.offsetLeft; // reflow\n });\n\n if(!icon) {\n icon = document.createElement('span');\n icon.classList.add('tgico-reply_filled', 'bubble-gesture-reply-icon');\n } else {\n icon.classList.remove('is-visible');\n icon.style.opacity = '';\n }\n\n target/* .querySelector('.bubble-content') */.append(icon);\n }\n\n return !!target;\n },\n onSwipe: (xDiff) => {\n shouldReply = xDiff >= replyAfter;\n\n if(shouldReply && !icon.classList.contains('is-visible')) {\n icon.classList.add('is-visible');\n }\n icon.style.opacity = '' + Math.min(1, xDiff / replyAfter);\n\n const x = -Math.max(0, Math.min(MAX, xDiff));\n const transform = `translateX(${x}px)`;\n target.style.transform = transform;\n if(swipeAvatar) {\n swipeAvatar.style.transform = transform;\n }\n cancelContextMenuOpening();\n },\n onReset: () => {\n const _target = target;\n const _swipeAvatar = swipeAvatar;\n target = swipeAvatar = undefined;\n\n const onTransitionEnd = () => {\n if(icon.parentElement === _target) {\n icon.classList.remove('is-visible');\n icon.remove();\n }\n };\n\n [_target, _swipeAvatar].filter(Boolean).forEach((element, idx) => {\n SetTransition({\n element,\n className,\n forwards: false,\n duration: 250,\n onTransitionEnd: idx === 0 ? onTransitionEnd : undefined\n });\n });\n\n fastRaf(() => {\n _target.style.transform = '';\n if(_swipeAvatar) {\n _swipeAvatar.style.transform = '';\n }\n\n if(shouldReply) {\n const {mid} = _target.dataset;\n this.chat.input.initMessageReply(+mid);\n shouldReply = false;\n }\n });\n },\n listenerOptions: {capture: true}\n });\n }\n }\n\n public constructPeerHelpers() {\n // will call when message is sent (only 1)\n this.listenerSetter.add(rootScope)('history_append', async({storageKey, message}) => {\n if(storageKey !== this.chat.messagesStorageKey || this.chat.type === 'scheduled') return;\n\n if(liteMode.isAvailable('chat_background')) {\n this.updateGradient = true;\n }\n\n if(!this.scrollable.loadedAll.bottom) {\n this.chat.setMessageId();\n } else {\n this.renderNewMessage(message, true);\n }\n });\n\n this.listenerSetter.add(rootScope)('history_multiappend', (message) => {\n if(this.peerId !== message.peerId || this.chat.type === 'scheduled') return;\n this.renderNewMessage(message);\n });\n\n this.listenerSetter.add(rootScope)('history_delete', ({peerId, msgs}) => {\n if(peerId !== this.peerId || this.chat.type === 'scheduled') {\n return;\n }\n\n this.deleteMessagesByIds(Array.from(msgs));\n });\n\n this.listenerSetter.add(rootScope)('dialog_unread', ({peerId}) => {\n if(peerId === this.peerId) {\n this.chat.input.setUnreadCount();\n\n getHeavyAnimationPromise().then(() => {\n this.updateUnreadByDialog();\n });\n }\n });\n\n this.listenerSetter.add(rootScope)('dialogs_multiupdate', (dialogs) => {\n if(!dialogs.has(this.peerId) || this.chat.type === 'scheduled') {\n return;\n }\n\n this.chat.input.setUnreadCount();\n });\n\n this.listenerSetter.add(rootScope)('dialog_notify_settings', (dialog) => {\n if(this.peerId !== dialog.peerId || this.chat.type === 'scheduled') {\n return;\n }\n\n this.chat.input.setUnreadCount();\n });\n\n this.listenerSetter.add(rootScope)('chat_update', async(chatId) => {\n const {peerId} = this;\n if(peerId !== chatId.toPeerId(true)) {\n return;\n }\n\n const chat = await this.managers.appChatsManager.getChat(chatId);\n const hadRights = this.chatInner.classList.contains('has-rights');\n const hadPlainRights = this.chat.input.canSendPlain();\n const [hasRights, hasPlainRights, canEmbedLinks] = await Promise.all([\n this.chat.canSend('send_messages'),\n this.chat.canSend('send_plain'),\n this.chat.canSend('embed_links')\n ]);\n\n if(hadRights !== hasRights || hadPlainRights !== hasPlainRights) {\n const callbacks = await Promise.all([\n this.finishPeerChange(),\n this.chat.input.finishPeerChange({middleware: this.getMiddleware()})\n ]);\n\n callbacks.forEach((callback) => callback());\n }\n\n // reset webpage\n if((canEmbedLinks && !this.chat.input.willSendWebPage) || (!canEmbedLinks && this.chat.input.willSendWebPage)) {\n this.chat.input.lastUrl = '';\n this.chat.input.onMessageInput();\n }\n\n if(!!(chat as MTChat.channel).pFlags.forum !== this.chat.isForum && this.chat.type === 'chat') {\n this.chat.peerId = 0;\n this.chat.appImManager.setPeer({peerId});\n }\n });\n\n this.listenerSetter.add(rootScope)('history_reload', (peerId) => {\n if(peerId !== this.peerId) {\n return;\n }\n\n const mids = getObjectKeysAndSort(this.bubbles, 'desc').filter((mid) => mid > 0);\n const middleware = this.getMiddleware();\n this.managers.appMessagesManager.reloadMessages(this.peerId, mids).then((messages) => {\n if(!middleware()) return;\n\n const toDelete: number[] = [];\n messages.forEach((message, idx) => {\n const mid = mids[idx];\n if(message) {\n const bubble = this.bubbles[message.mid];\n if(!bubble) return;\n\n this.safeRenderMessage(message, true, bubble);\n } else {\n toDelete.push(mid);\n }\n });\n\n this.deleteMessagesByIds(toDelete);\n\n this.setLoaded('top', false);\n this.setLoaded('bottom', false);\n this.scrollable.checkForTriggers();\n });\n });\n\n this.listenerSetter.add(rootScope)('settings_updated', async({key}) => {\n if(key === 'settings.emoji.big') {\n const middleware = this.getMiddleware();\n const mids = getObjectKeysAndSort(this.bubbles, 'desc');\n const m = mids.map(async(mid) => {\n const bubble = this.bubbles[mid];\n if(bubble.classList.contains('can-have-big-emoji')) {\n return {bubble, message: await this.chat.getMessage(mid)};\n }\n });\n\n const awaited = await Promise.all(m);\n if(!middleware()) {\n return;\n }\n\n awaited.filter(Boolean).forEach(({bubble, message}) => {\n if(this.bubbles[message.mid] !== bubble) {\n return;\n }\n\n this.safeRenderMessage(message, true, bubble);\n });\n }\n });\n\n !DO_NOT_UPDATE_MESSAGE_VIEWS && this.listenerSetter.add(rootScope)('messages_views', (arr) => {\n if(this.chat.type === 'scheduled') return;\n\n fastRaf(() => {\n let scrollSaver: ScrollSaver;\n for(const {peerId, views, mid} of arr) {\n if(this.peerId !== peerId) continue;\n\n const bubble = this.bubbles[mid];\n if(!bubble) continue;\n\n const postViewsElements = Array.from(bubble.querySelectorAll('.post-views')) as HTMLElement[];\n if(!postViewsElements.length) continue;\n\n const str = formatNumber(views, 1);\n let different = false;\n postViewsElements.forEach((postViews) => {\n if(different || postViews.textContent !== str) {\n if(!scrollSaver) {\n scrollSaver = this.createScrollSaver(true);\n scrollSaver.save();\n }\n\n different = true;\n postViews.textContent = str;\n }\n });\n }\n\n scrollSaver?.restore();\n });\n });\n\n this.observer = new SuperIntersectionObserver({root: this.scrollable.container});\n\n this.sendViewCountersDebounced = debounce(() => {\n const mids = [...this.viewsMids];\n this.viewsMids.clear();\n\n this.managers.appMessagesManager.incrementMessageViews(this.peerId, mids);\n }, 1000, false, true);\n\n // * pinned part start\n this.listenerSetter.add(rootScope)('peer_pinned_messages', ({peerId, mids, pinned}) => {\n if(this.chat.type !== 'pinned' || peerId !== this.peerId) {\n return;\n }\n\n if(mids) {\n if(!pinned) {\n this.deleteMessagesByIds(mids);\n }\n }\n });\n // * pinned part end\n\n // * scheduled part start\n const onUpdate = async() => {\n this.chat.topbar.setTitle((await this.managers.appMessagesManager.getScheduledMessagesStorage(this.peerId)).size);\n };\n\n this.listenerSetter.add(rootScope)('scheduled_new', (message) => {\n if(this.chat.type !== 'scheduled' || message.peerId !== this.peerId) return;\n\n this.renderNewMessage(message);\n onUpdate();\n });\n\n this.listenerSetter.add(rootScope)('scheduled_delete', ({peerId, mids}) => {\n if(this.chat.type !== 'scheduled' || peerId !== this.peerId) return;\n\n this.deleteMessagesByIds(mids);\n onUpdate();\n });\n // * scheduled part end\n }\n\n private get peerId() {\n return this.chat.peerId;\n }\n\n public get messagesQueuePromise() {\n return this.batchProcessor.queuePromise;\n }\n\n private createScrollSaver(reverse = true) {\n const scrollSaver = new ScrollSaver(this.scrollable, '.bubble:not(.is-date)', reverse);\n return scrollSaver;\n }\n\n private unreadedObserverCallback = (entry: IntersectionObserverEntry) => {\n if(entry.isIntersecting) {\n const target = entry.target as HTMLElement;\n const mid = this.unreaded.get(target as HTMLElement);\n this.onUnreadedInViewport(target, mid);\n }\n };\n\n private viewsObserverCallback = (entry: IntersectionObserverEntry) => {\n if(entry.isIntersecting) {\n const mid = +(entry.target as HTMLElement).dataset.mid;\n this.observer.unobserve(entry.target, this.viewsObserverCallback);\n\n if(mid) {\n this.viewsMids.add(mid);\n this.sendViewCountersDebounced();\n } else {\n const {sponsoredMessage} = this;\n const randomId = sponsoredMessage?.random_id;\n if(randomId) {\n this.managers.appChatsManager.viewSponsoredMessage(this.peerId.toChatId(), randomId);\n delete sponsoredMessage.random_id;\n }\n }\n }\n };\n\n private stickerEffectObserverCallback = (entry: IntersectionObserverEntry) => {\n if(entry.isIntersecting) {\n this.observer.unobserve(entry.target, this.stickerEffectObserverCallback);\n\n const attachmentDiv: HTMLElement = entry.target.querySelector('.attachment');\n getHeavyAnimationPromise().then(() => {\n if(isInDOM(attachmentDiv)) {\n simulateClickEvent(attachmentDiv);\n }\n });\n }\n };\n\n private createResizeObserver() {\n if(!('ResizeObserver' in window) || this.resizeObserver) {\n return;\n }\n\n const container = this.scrollable.container;\n let wasHeight = 0/* container.offsetHeight */;\n let resizing = false;\n let skip = false;\n let scrolled = 0;\n let part = 0;\n let rAF = 0;\n // let skipNext = true;\n\n const onResizeEnd = () => {\n const height = container.offsetHeight;\n const isScrolledDown = this.scrollable.isScrolledDown;\n if(height !== wasHeight && (!skip || !isScrolledDown)) { // * fix opening keyboard while ESG is active, offsetHeight will change right between 'start' and this first frame\n part += wasHeight - height;\n }\n\n /* if(DEBUG) {\n this.log('resize end', scrolled, part, this.scrollable.scrollTop, height, wasHeight, this.scrollable.isScrolledDown);\n } */\n\n if(part) {\n this.scrollable.setScrollTopSilently(this.scrollable.scrollTop + Math.round(part));\n }\n\n wasHeight = height;\n scrolled = 0;\n rAF = 0;\n part = 0;\n resizing = false;\n skip = false;\n };\n\n const setEndRAF = (single: boolean) => {\n if(rAF) window.cancelAnimationFrame(rAF);\n rAF = window.requestAnimationFrame(single ? onResizeEnd : () => {\n rAF = window.requestAnimationFrame(onResizeEnd);\n // this.log('resize after RAF', part);\n });\n };\n\n const processEntries: ResizeObserverCallback = (entries) => {\n /* if(skipNext) {\n skipNext = false;\n return;\n } */\n\n if(skip) {\n setEndRAF(false);\n return;\n }\n\n const entry = entries[0];\n const height = entry.contentRect.height;/* Math.ceil(entry.contentRect.height); */\n\n if(!wasHeight) {\n wasHeight = height;\n return;\n }\n\n const realDiff = wasHeight - height;\n let diff = realDiff + part;\n const _part = diff % 1;\n diff -= _part;\n\n if(!resizing) {\n resizing = true;\n\n /* if(DEBUG) {\n this.log('resize start', realDiff, this.scrollable.scrollTop, this.scrollable.container.offsetHeight, this.scrollable.isScrolledDown);\n } */\n\n if(realDiff < 0 && this.scrollable.isScrolledDown) {\n // if(isSafari) { // * fix opening keyboard while ESG is active\n part = -realDiff;\n // }\n\n skip = true;\n setEndRAF(false);\n return;\n }\n }\n\n scrolled += diff;\n\n /* if(DEBUG) {\n this.log('resize', wasHeight - height, diff, this.scrollable.container.offsetHeight, this.scrollable.isScrolledDown, height, wasHeight);\n } */\n\n if(diff) {\n const needScrollTop = this.scrollable.scrollTop + diff;\n this.scrollable.setScrollTopSilently(needScrollTop);\n }\n\n setEndRAF(false);\n\n part = _part;\n wasHeight = height;\n };\n\n const resizeObserver = this.resizeObserver = new ResizeObserver(processEntries);\n resizeObserver.observe(container);\n }\n\n private destroyResizeObserver() {\n const resizeObserver = this.resizeObserver;\n if(!resizeObserver) {\n return;\n }\n\n resizeObserver.disconnect();\n this.resizeObserver = undefined;\n }\n\n private onBubblesMouseMove = async(e: MouseEvent) => {\n const content = findUpClassName(e.target, 'bubble-content');\n if(\n this.chat.type !== 'scheduled' &&\n content &&\n !this.chat.selection.isSelecting &&\n !findUpClassName(e.target, 'service') &&\n !findUpClassName(e.target, 'bubble-beside-button')\n ) {\n const bubble = findUpClassName(content, 'bubble');\n if(!this.chat.selection.canSelectBubble(bubble)) {\n this.unhoverPrevious();\n return;\n }\n\n let {hoverBubble, hoverReaction} = this;\n if(bubble === hoverBubble) {\n return;\n }\n\n this.unhoverPrevious();\n\n hoverBubble = this.hoverBubble = bubble;\n hoverReaction = this.hoverReaction;\n // hoverReaction = contentWrapper.querySelector('.bubble-hover-reaction');\n if(!hoverReaction) {\n hoverReaction = this.hoverReaction = document.createElement('div');\n hoverReaction.classList.add('bubble-hover-reaction');\n\n const stickerWrapper = document.createElement('div');\n stickerWrapper.classList.add('bubble-hover-reaction-sticker');\n hoverReaction.append(stickerWrapper);\n\n content.append(hoverReaction);\n\n let message = await this.chat.getMessage(+bubble.dataset.mid);\n if(message?._ !== 'message') {\n this.unhoverPrevious();\n return;\n }\n\n message = await this.managers.appMessagesManager.getGroupsFirstMessage(message);\n\n const middleware = this.getMiddleware(() => this.hoverReaction === hoverReaction);\n Promise.all([\n this.managers.appReactionsManager.getAvailableReactionsByMessage(message),\n pause(400)\n ]).then(([availableReactions]) => {\n const availableReaction = availableReactions[0];\n if(!availableReaction) {\n hoverReaction.remove();\n return;\n }\n\n wrapSticker({\n div: stickerWrapper,\n doc: availableReaction.select_animation,\n width: 18,\n height: 18,\n needUpscale: true,\n middleware,\n group: this.chat.animationGroup,\n withThumb: false,\n needFadeIn: false\n }).then(({render}) => render).then((player) => {\n assumeType<RLottiePlayer>(player);\n\n player.addEventListener('firstFrame', () => {\n if(!middleware()) {\n // debugger;\n return;\n }\n\n hoverReaction.dataset.loaded = '1';\n this.setHoverVisible(hoverReaction, true);\n }, {once: true});\n\n attachClickEvent(hoverReaction, (e) => {\n cancelEvent(e); // cancel triggering selection\n\n this.managers.appReactionsManager.sendReaction(message as Message.message, availableReaction);\n this.unhoverPrevious();\n }, {listenerSetter: this.listenerSetter});\n }, noop);\n });\n } else if(hoverReaction.dataset.loaded) {\n this.setHoverVisible(hoverReaction, true);\n }\n } else {\n this.unhoverPrevious();\n }\n };\n\n public setReactionsHoverListeners() {\n this.listenerSetter.add(contextMenuController)('toggle', this.unhoverPrevious);\n this.listenerSetter.add(overlayCounter)('change', this.unhoverPrevious);\n this.listenerSetter.add(this.chat.selection)('toggle', this.unhoverPrevious);\n this.listenerSetter.add(this.container)('mousemove', this.onBubblesMouseMove);\n }\n\n private setHoverVisible(hoverReaction: HTMLElement, visible: boolean) {\n if(hoverReaction.parentElement) {\n hoverReaction.parentElement.classList.toggle('hover-reaction-visible', visible);\n }\n\n SetTransition({\n element: hoverReaction,\n className: 'is-visible',\n forwards: visible,\n duration: 200,\n onTransitionEnd: visible ? undefined : () => {\n hoverReaction.remove();\n },\n useRafs: 2\n });\n }\n\n private unhoverPrevious = () => {\n const {hoverBubble, hoverReaction} = this;\n if(hoverBubble) {\n this.setHoverVisible(hoverReaction, false);\n this.hoverBubble = undefined;\n this.hoverReaction = undefined;\n }\n };\n\n public setStickyDateManually() {\n return;\n\n const timestamps = Object.keys(this.dateMessages).map((k) => +k).sort((a, b) => b - a);\n let lastVisible: HTMLElement;\n\n // if(this.chatInner.classList.contains('is-scrolling')) {\n const {scrollTop} = this.scrollable.container;\n const isOverflown = scrollTop > 0;\n if(isOverflown) {\n for(const timestamp of timestamps) {\n const dateMessage = this.dateMessages[timestamp];\n const visibleRect = getVisibleRect(dateMessage.container, this.scrollable.container);\n if(visibleRect && visibleRect.overflow.top) {\n lastVisible = dateMessage.div;\n } else if(lastVisible) {\n break;\n }\n }\n }\n // }\n\n if(lastVisible === this.previousStickyDate) {\n return;\n }\n\n if(lastVisible) {\n const needReflow = /* !!this.chat.setPeerPromise || */!this.previousStickyDate;\n if(needReflow) {\n lastVisible.classList.add('no-transition');\n }\n\n lastVisible.classList.add('is-sticky');\n\n if(needReflow) {\n void lastVisible.offsetLeft; // reflow\n lastVisible.classList.remove('no-transition');\n }\n }\n\n if(this.previousStickyDate && this.previousStickyDate !== lastVisible) {\n this.previousStickyDate.classList.remove('is-sticky');\n }\n\n this.previousStickyDate = lastVisible;\n }\n\n public getRenderedLength() {\n return Object.keys(this.bubbles).length - this.skippedMids.size;\n }\n\n private onUnreadedInViewport(target: HTMLElement, mid: number) {\n this.unreadedSeen.add(mid);\n this.observer.unobserve(target, this.unreadedObserverCallback);\n this.unreaded.delete(target);\n this.readUnreaded();\n }\n\n private readUnreaded() {\n if(this.readPromise) return;\n\n const middleware = this.getMiddleware();\n this.readPromise = idleController.getFocusPromise().then(async() => {\n if(!middleware()) return;\n let maxId = Math.max(...Array.from(this.unreadedSeen));\n\n // ? if message with maxId is not rendered ?\n if(this.scrollable.loadedAll.bottom) {\n const bubblesMaxId = Math.max(...Object.keys(this.bubbles).map((i) => +i));\n if(maxId >= bubblesMaxId) {\n maxId = Math.max((await this.chat.getHistoryMaxId()) || 0, maxId);\n }\n }\n\n this.unreaded.forEach((mid, target) => {\n if(mid <= maxId) {\n this.onUnreadedInViewport(target, mid);\n }\n });\n\n const readContents: number[] = [];\n for(const mid of this.unreadedSeen) {\n const message: MyMessage = await this.chat.getMessage(mid);\n if(isMentionUnread(message)) {\n readContents.push(mid);\n }\n }\n\n this.managers.appMessagesManager.readMessages(this.peerId, readContents);\n\n this.unreadedSeen.clear();\n\n if(DEBUG) {\n this.log('will readHistory by maxId:', maxId);\n }\n\n // return;\n\n return this.managers.appMessagesManager.readHistory(this.peerId, maxId, this.chat.threadId).catch((err: any) => {\n this.log.error('readHistory err:', err);\n this.managers.appMessagesManager.readHistory(this.peerId, maxId, this.chat.threadId);\n }).finally(() => {\n if(!middleware()) return;\n this.readPromise = undefined;\n\n if(this.unreadedSeen.size) {\n this.readUnreaded();\n }\n });\n });\n }\n\n public onBubblesClick = async(e: Event) => {\n let target = e.target as HTMLElement;\n let bubble: HTMLElement = null;\n try {\n bubble = findUpClassName(target, 'bubble');\n } catch(err) {}\n\n if(!bubble && !this.chat.selection.isSelecting) {\n const avatar = findUpClassName(target, 'user-avatar');\n if(!avatar) {\n return;\n }\n\n const peerId = avatar.dataset.peerId.toPeerId();\n if(peerId !== NULL_PEER_ID) {\n this.chat.appImManager.setInnerPeer({peerId});\n } else {\n toast(I18n.format('HidAccount', true));\n }\n return;\n }\n\n if(bubble.classList.contains('is-date') && findUpClassName(target, 'bubble-content')) {\n if(bubble.classList.contains('is-fake')) {\n bubble = bubble.previousElementSibling as HTMLElement;\n }\n\n if(bubble.classList.contains('is-sticky') && !this.chatInner.classList.contains('is-scrolling')) {\n return;\n }\n\n for(const timestamp in this.dateMessages) {\n const d = this.dateMessages[timestamp];\n if(d.div === bubble) {\n PopupElement.createPopup(PopupDatePicker, new Date(+timestamp), this.onDatePick).show();\n break;\n }\n }\n\n return;\n }\n\n if(!IS_TOUCH_SUPPORTED && findUpClassName(target, 'time')) {\n this.chat.selection.toggleByElement(bubble);\n return;\n }\n\n // ! Trusted - due to audio autoclick\n if(this.chat.selection.isSelecting && e.isTrusted) {\n if(bubble.classList.contains('service') && bubble.dataset.mid === undefined) {\n return;\n }\n\n cancelEvent(e);\n // console.log('bubble click', e);\n\n if(IS_TOUCH_SUPPORTED && this.chat.selection.selectedText) {\n this.chat.selection.selectedText = undefined;\n return;\n }\n\n // this.chatSelection.toggleByBubble(bubble);\n this.chat.selection.toggleByElement(findUpClassName(target, 'grouped-item') || bubble);\n return;\n }\n\n const mediaSpoiler: HTMLElement = findUpClassName(target, 'media-spoiler-container');\n if(mediaSpoiler) {\n onMediaSpoilerClick({\n event: e,\n mediaSpoiler\n });\n return;\n }\n\n const contactDiv: HTMLElement = findUpClassName(target, 'contact');\n if(contactDiv) {\n const peerId = contactDiv.dataset.peerId.toPeerId();\n if(peerId) {\n this.chat.appImManager.setInnerPeer({\n peerId\n });\n } else {\n const phone = contactDiv.querySelector<HTMLElement>('.contact-number');\n copyTextToClipboard(phone.innerText.replace(/\\s/g, ''));\n toastNew({langPackKey: 'PhoneCopied'});\n cancelEvent(e);\n }\n\n return;\n }\n\n const callDiv: HTMLElement = findUpClassName(target, 'bubble-call');\n if(callDiv) {\n this.chat.appImManager.callUser(this.peerId.toUserId(), callDiv.dataset.type as any);\n return;\n }\n\n const buyButton: HTMLElement = findUpClassName(target, 'is-buy');\n if(buyButton) {\n cancelEvent(e);\n\n const message = await this.chat.getMessage(+bubble.dataset.mid);\n if(!message) {\n return;\n }\n\n PopupElement.createPopup(\n PopupPayment,\n message as Message.message,\n await this.managers.appPaymentsManager.getInputInvoiceByPeerId(message.peerId, message.mid)\n );\n return;\n }\n\n const reactionElement = findUpTag(target, 'REACTION-ELEMENT') as ReactionElement;\n if(reactionElement) {\n cancelEvent(e);\n if(reactionElement.classList.contains('is-inactive')) {\n return;\n }\n\n const reactionsElement = reactionElement.parentElement as ReactionsElement;\n const reactionCount = reactionsElement.getReactionCount(reactionElement);\n\n const message = reactionsElement.getMessage();\n this.managers.appReactionsManager.sendReaction(message, reactionCount.reaction);\n\n return;\n }\n\n const stickerEmojiEl = findUpAttribute(target, 'data-sticker-emoji');\n if(stickerEmojiEl && stickerEmojiEl.parentElement.querySelectorAll('[data-sticker-emoji]').length === 1 && bubble.classList.contains('emoji-big')) {\n onEmojiStickerClick({\n event: e,\n container: stickerEmojiEl,\n managers: this.managers,\n middleware: this.getMiddleware(),\n peerId: this.peerId\n });\n\n return;\n }\n\n const commentsDiv: HTMLElement = findUpClassName(target, 'replies');\n if(commentsDiv) {\n const bubbleMid = +bubble.dataset.mid;\n if(this.peerId === REPLIES_PEER_ID) {\n const message = await this.chat.getMessage(bubbleMid) as Message.message;\n const peerId = getPeerId(message.reply_to.reply_to_peer_id);\n const threadId = message.reply_to.reply_to_top_id;\n const lastMsgId = message.fwd_from.saved_from_msg_id;\n this.chat.appImManager.openThread({\n peerId,\n lastMsgId,\n threadId\n });\n } else {\n const message1 = await this.chat.getMessage(bubbleMid);\n const message = await this.managers.appMessagesManager.getMessageWithReplies(message1 as Message.message);\n const replies = message.replies;\n if(replies) {\n this.managers.appMessagesManager.getDiscussionMessage(this.peerId, message.mid).then((message) => {\n this.chat.appImManager.setInnerPeer({\n peerId: replies.channel_id.toPeerId(true),\n type: 'discussion',\n threadId: (message as MyMessage).mid\n });\n });\n }\n }\n\n return;\n }\n\n const via = findUpClassName(target, 'is-via');\n if(via) {\n const el = via.querySelector('.peer-title') as HTMLElement;\n if(target === el || findUpAsChild(target, el)) {\n const message = el.innerText + ' ';\n this.managers.appDraftsManager.setDraft(this.peerId, this.chat.threadId, message);\n cancelEvent(e);\n\n return;\n }\n }\n\n const nameDiv = findUpClassName(target, 'peer-title') || findUpTag(target, 'AVATAR-ELEMENT') || findUpAttribute(target, 'data-saved-from');\n if(nameDiv && nameDiv !== bubble) {\n target = nameDiv || target;\n const peerIdStr = target.dataset.peerId || target.getAttribute('peer') || (target as AvatarElement).peerId;\n const savedFrom = target.dataset.savedFrom;\n if(typeof(peerIdStr) === 'string' || savedFrom) {\n if(savedFrom) {\n const [peerId, mid] = savedFrom.split('_');\n if(target.classList.contains('is-receipt-link')) {\n const message = await this.managers.appMessagesManager.getMessageByPeer(peerId.toPeerId(), +mid);\n if(message) {\n const inputInvoice = await this.managers.appPaymentsManager.getInputInvoiceByPeerId(this.peerId, +bubble.dataset.mid);\n PopupElement.createPopup(PopupPayment, message as Message.message, inputInvoice, undefined, true);\n }\n } else {\n this.chat.appImManager.setInnerPeer({\n peerId: peerId.toPeerId(),\n lastMsgId: +mid\n });\n }\n } else {\n const peerId = peerIdStr.toPeerId();\n if(peerId !== NULL_PEER_ID) {\n this.chat.appImManager.setInnerPeer({peerId});\n } else {\n toast(I18n.format('HidAccount', true));\n }\n }\n }\n\n return;\n }\n\n // this.log('chatInner click:', target);\n // const isVideoComponentElement = target.tagName === 'SPAN' && findUpClassName(target, 'media-container');\n /* if(isVideoComponentElement) {\n const video = target.parentElement.querySelector('video') as HTMLElement;\n if(video) {\n video.click(); // hot-fix for time and play button\n return;\n }\n } */\n\n if(bubble.classList.contains('sticker') && target.parentElement.classList.contains('attachment')) {\n const messageId = +bubble.dataset.mid;\n const message = await this.chat.getMessage(messageId);\n\n const doc = ((message as Message.message).media as MessageMedia.messageMediaDocument)?.document as Document.document;\n\n if(doc?.stickerSetInput) {\n PopupElement.createPopup(PopupStickers, doc.stickerSetInput).show();\n }\n\n return;\n }\n\n if(await this.checkTargetForMediaViewer(target, e)) {\n return;\n }\n\n if(['IMG', 'DIV', 'SPAN'/* , 'A' */].indexOf(target.tagName) === -1) target = findUpTag(target, 'DIV');\n\n if(['DIV', 'SPAN'].indexOf(target.tagName) !== -1/* || target.tagName === 'A' */) {\n if(target.classList.contains('goto-original')) {\n const savedFrom = bubble.dataset.savedFrom;\n const [peerId, mid] = savedFrom.split('_');\n // //this.log('savedFrom', peerId, msgID);\n this.chat.appImManager.setInnerPeer({\n peerId: peerId.toPeerId(),\n lastMsgId: +mid\n });\n return;\n } else if(target.classList.contains('forward')) {\n const mid = +bubble.dataset.mid;\n const message = await this.managers.appMessagesManager.getMessageByPeer(this.peerId, mid);\n PopupElement.createPopup(PopupForward, {\n [this.peerId]: await this.managers.appMessagesManager.getMidsByMessage(message)\n });\n // appSidebarRight.forwardTab.open([mid]);\n return;\n }\n\n let isReplyClick = false;\n\n try {\n isReplyClick = !!findUpClassName(e.target, 'reply');\n } catch(err) {}\n\n if(isReplyClick && bubble.classList.contains('is-reply')/* || bubble.classList.contains('forwarded') */) {\n const bubbleMid = +bubble.dataset.mid;\n this.followStack.push(bubbleMid);\n\n const message = (await this.chat.getMessage(bubbleMid)) as Message.message;\n\n const replyToPeerId = message.reply_to.reply_to_peer_id ? getPeerId(message.reply_to.reply_to_peer_id) : this.peerId;\n const replyToMid = message.reply_to.reply_to_msg_id;\n\n this.chat.appImManager.setInnerPeer({\n peerId: replyToPeerId,\n lastMsgId: replyToMid,\n type: this.chat.type,\n threadId: this.chat.threadId\n });\n\n /* if(this.chat.type === 'discussion') {\n this.chat.appImManager.setMessageId(, originalMessageId);\n } else {\n this.chat.appImManager.setInnerPeer(this.peerId, originalMessageId);\n } */\n // this.chat.setMessageId(, originalMessageId);\n }\n }\n\n // console.log('chatInner click', e);\n };\n\n public async checkTargetForMediaViewer(target: HTMLElement, e?: Event, mediaTimestamp?: number) {\n const bubble = findUpClassName(target, 'bubble');\n const documentDiv = findUpClassName(target, 'document-with-thumb');\n if((target.tagName === 'IMG' && !target.classList.contains('emoji') && !target.classList.contains('document-thumb')) ||\n target.classList.contains('album-item') ||\n // || isVideoComponentElement\n (target.tagName === 'VIDEO' && !bubble.classList.contains('round')) ||\n (documentDiv && !documentDiv.querySelector('.preloader-container')) ||\n target.classList.contains('canvas-thumbnail')) {\n const groupedItem = findUpClassName(target, 'album-item') || findUpClassName(target, 'document-container');\n const preloader = (groupedItem || bubble).querySelector<HTMLElement>('.preloader-container');\n if(preloader && e) {\n simulateClickEvent(preloader);\n cancelEvent(e);\n return;\n }\n\n cancelEvent(e);\n const messageId = +(groupedItem || bubble).dataset.mid;\n const message = await this.chat.getMessage(messageId);\n if(!message) {\n this.log.warn('no message by messageId:', messageId);\n return;\n }\n\n const SINGLE_MEDIA_CLASSNAME = 'webpage';\n const isSingleMedia = bubble.classList.contains(SINGLE_MEDIA_CLASSNAME);\n\n const f = documentDiv ? (media: any) => {\n return AppMediaViewer.isMediaCompatibleForDocumentViewer(media);\n } : (media: any) => {\n return media._ === 'photo' || ['video', 'gif'].includes(media.type);\n };\n\n const targets: {element: HTMLElement, mid: number, peerId: PeerId}[] = [];\n const ids = isSingleMedia ? [messageId] : (await Promise.all(Object.keys(this.bubbles).map((k) => +k).map(async(mid) => {\n /* if(isSingleMedia && !this.bubbles[id].classList.contains(SINGLE_MEDIA_CLASSNAME)) {\n return false;\n } */\n // if(!this.scrollable.visibleElements.find((e) => e.element === this.bubbles[id])) return false;\n\n const message = await this.chat.getMessage(mid);\n const media = getMediaFromMessage(message);\n\n return media && f(media) && mid;\n }))).filter(Boolean).sort((a, b) => a - b);\n\n ids.forEach((id) => {\n let selector: string;\n if(documentDiv) {\n selector = '.document-container';\n } else {\n const withTail = this.bubbles[id].classList.contains('with-media-tail');\n selector = '.album-item video, .album-item img, .preview video, .preview img, ';\n if(withTail) {\n selector += '.bubble__media-container';\n } else {\n selector += '.attachment video, .attachment img';\n }\n }\n\n const elements = Array.from(this.bubbles[id].querySelectorAll(selector)) as HTMLElement[];\n const parents: Set<HTMLElement> = new Set();\n if(documentDiv) {\n elements.forEach((element) => {\n targets.push({\n element: element.querySelector('.document-ico'),\n mid: +element.dataset.mid,\n peerId: this.peerId\n });\n });\n } else {\n const hasAspecter = !!this.bubbles[id].querySelector('.media-container-aspecter');\n elements.forEach((element) => {\n if(hasAspecter && !findUpClassName(element, 'media-container-aspecter')) return;\n const albumItem = findUpClassName(element, 'album-item');\n const parent = albumItem || element.parentElement;\n if(parents.has(parent)) return;\n parents.add(parent);\n targets.push({\n element,\n mid: albumItem ? +albumItem.dataset.mid : id,\n peerId: this.peerId\n });\n });\n }\n });\n\n targets.sort((a, b) => a.mid - b.mid);\n\n const idx = targets.findIndex((t) => t.mid === messageId);\n\n if(DEBUG) {\n this.log('open mediaViewer single with ids:', ids, idx, targets);\n }\n\n if(!targets[idx]) {\n this.log('no target for media viewer!', target);\n return;\n }\n\n new AppMediaViewer()\n .setSearchContext({\n threadId: this.chat.threadId,\n peerId: this.peerId,\n inputFilter: {_: documentDiv ? 'inputMessagesFilterDocument' : 'inputMessagesFilterPhotoVideo'},\n useSearch: this.chat.type !== 'scheduled' && !isSingleMedia,\n isScheduled: this.chat.type === 'scheduled'\n })\n .openMedia({\n message: message,\n target: targets[idx].element,\n fromRight: 0,\n reverse: true,\n prevTargets: targets.slice(0, idx),\n nextTargets: targets.slice(idx + 1),\n mediaTimestamp\n });\n return true;\n }\n }\n\n public async onGoDownClick() {\n if(!this.followStack.length) {\n // this.onScroll(true, undefined, true);\n this.chat.setMessageId(/* , dialog.top_message */);\n // const dialog = this.appMessagesManager.getDialogByPeerId(this.peerId)[0];\n\n // if(dialog) {\n // this.chat.setPeer(this.peerId/* , dialog.top_message */);\n // } else {\n // this.log('will scroll down 3');\n // this.scroll.scrollTop = this.scroll.scrollHeight;\n // }\n\n return;\n }\n\n const middleware = this.getMiddleware();\n const slice = this.followStack.slice();\n const messages = await Promise.all(slice.map((mid) => this.chat.getMessage(mid)));\n if(!middleware()) return;\n\n slice.forEach((mid, idx) => {\n const message = messages[idx];\n\n const bubble = this.bubbles[mid];\n let bad = true;\n if(bubble) {\n const rect = bubble.getBoundingClientRect();\n bad = (windowSize.height / 2) > rect.top;\n } else if(message) {\n bad = false;\n }\n\n if(bad) {\n this.followStack.splice(this.followStack.indexOf(mid), 1);\n }\n });\n\n this.followStack.sort((a, b) => b - a);\n\n const mid = this.followStack.pop();\n this.chat.setMessageId(mid);\n }\n\n public getBubbleByPoint(verticalSide: 'top' | 'bottom') {\n const slice = this.getViewportSlice();\n const item = slice.visible[verticalSide === 'top' ? 0 : slice.visible.length - 1];\n return item?.element;\n }\n\n public async getGroupedBubble(groupId: string) {\n const mids = await this.managers.appMessagesManager.getMidsByAlbum(groupId);\n for(const mid of mids) {\n if(this.bubbles[mid] && !this.skippedMids.has(mid)) {\n // const maxId = Math.max(...mids); // * because in scheduled album can be rendered by lowest mid during sending\n return {\n bubble: this.bubbles[mid],\n mid: mid\n // message: await this.chat.getMessage(maxId) as Message.message\n };\n }\n }\n }\n\n public getBubbleGroupedItems(bubble: HTMLElement) {\n return Array.from(bubble.querySelectorAll('.grouped-item')) as HTMLElement[];\n }\n\n public async getMountedBubble(mid: number, message?: Message.message | Message.messageService) {\n if(message === undefined) {\n message = await this.chat.getMessage(mid);\n }\n\n if(!message) {\n return;\n }\n\n const groupedId = (message as Message.message).grouped_id;\n if(groupedId) {\n const a = await this.getGroupedBubble(groupedId);\n if(a) {\n a.bubble = a.bubble.querySelector(`.document-container[data-mid=\"${mid}\"]`) || a.bubble;\n return a;\n }\n }\n\n const bubble = this.bubbles[mid];\n if(!bubble || this.skippedMids.has(mid)) return;\n\n return {bubble, mid};\n }\n\n private findNextMountedBubbleByMsgId(mid: number, prev?: boolean) {\n const mids = getObjectKeysAndSort(this.bubbles, prev ? 'desc' : 'asc');\n\n let filterCallback: (_mid: number) => boolean;\n if(prev) filterCallback = (_mid) => _mid < mid;\n else filterCallback = (_mid) => mid < _mid;\n\n const foundMid = mids.find((_mid) => {\n if(!filterCallback(_mid)) return false;\n return !!this.bubbles[_mid]?.parentElement;\n });\n\n return this.bubbles[foundMid];\n }\n\n public loadMoreHistory(top: boolean, justLoad = false) {\n // this.log('loadMoreHistory', top);\n if(\n !this.peerId ||\n /* TEST_SCROLL || */\n this.chat.setPeerPromise ||\n this.isHeavyAnimationInProgress ||\n (top && (this.getHistoryTopPromise || this.scrollable.loadedAll.top)) ||\n (!top && (this.getHistoryBottomPromise || this.scrollable.loadedAll.bottom))\n ) {\n return;\n }\n\n // warning, если иды только отрицательные то вниз не попадёт (хотя мб и так не попадёт)\n // some messages can have negative id (such as sponsored message)\n const history = Object.keys(this.bubbles)\n .map((id) => +id)\n .filter((id) => id > 0 && !this.skippedMids.has(id))\n .sort((a, b) => a - b);\n\n if(!history.length) {\n history.push(0);\n }\n\n if(top) {\n if(DEBUG) {\n this.log('Will load more (up) history by id:', history[0], 'maxId:', history[history.length - 1], justLoad/* , history */);\n }\n\n this.getHistory1(history[0], true, undefined, undefined, justLoad);\n } else {\n // let dialog = this.appMessagesManager.getDialogByPeerId(this.peerId)[0];\n // const historyMaxId = await this.chat.getHistoryMaxId();\n\n // // if scroll down after search\n // if(history.indexOf(historyMaxId) !== -1) {\n // this.setLoaded('bottom', true);\n // return;\n // }\n\n if(DEBUG) {\n this.log('Will load more (down) history by id:', history[history.length - 1], justLoad/* , history */);\n }\n\n this.getHistory1(history[history.length - 1], false, true, undefined, justLoad);\n }\n }\n\n public onScroll = (ignoreHeavyAnimation?: boolean, scrollDimensions?: ScrollStartCallbackDimensions, forceDown?: boolean) => {\n // return;\n\n if(this.isHeavyAnimationInProgress) {\n this.sliceViewportDebounced?.clearTimeout();\n\n // * В таком случае, кнопка не будет моргать если чат в самом низу, и правильно отработает случай написания нового сообщения и проскролла вниз\n if(this.scrolledDown && !ignoreHeavyAnimation) {\n return;\n }\n } else {\n this.chat.topbar.pinnedMessage?.setCorrectIndexThrottled(this.scrollable.lastScrollDirection);\n this.sliceViewportDebounced?.();\n this.setStickyDateManually();\n }\n\n // lottieLoader.checkAnimations(false, 'chat');\n\n if(scrollDimensions && scrollDimensions.distanceToEnd < SCROLLED_DOWN_THRESHOLD && this.scrolledDown) {\n return;\n }\n\n const distanceToEnd = forceDown ? 0 : scrollDimensions?.distanceToEnd ?? this.scrollable.getDistanceToEnd();\n if(/* !IS_TOUCH_SUPPORTED && */(this.scrollable.lastScrollDirection !== 0 && distanceToEnd > 0) || scrollDimensions || forceDown) {\n // if(/* !IS_TOUCH_SUPPORTED && */(this.scrollable.lastScrollDirection !== 0 || scrollDimensions) && distanceToEnd > 0) {\n if(this.isScrollingTimeout) {\n clearTimeout(this.isScrollingTimeout);\n } else if(!this.chatInner.classList.contains('is-scrolling')) {\n this.chatInner.classList.add('is-scrolling');\n }\n\n this.isScrollingTimeout = window.setTimeout(() => {\n this.chatInner.classList.remove('is-scrolling');\n this.isScrollingTimeout = 0;\n }, 1350 + (scrollDimensions?.duration ?? 0));\n }\n\n if(distanceToEnd < SCROLLED_DOWN_THRESHOLD && (forceDown || this.scrollable.loadedAll.bottom || this.chat.setPeerPromise || !this.peerId)) {\n this.container.classList.add('scrolled-down');\n this.scrolledDown = true;\n } else if(this.container.classList.contains('scrolled-down')) {\n this.container.classList.remove('scrolled-down');\n this.scrolledDown = false;\n }\n };\n\n public setScroll() {\n if(this.scrollable) {\n this.destroyScrollable();\n }\n\n this.scrollable = new Scrollable(null, 'IM', /* 10300 */300);\n this.setLoaded('top', false, false);\n this.setLoaded('bottom', false, false);\n\n this.scrollable.container.append(this.chatInner);\n\n /* const getScrollOffset = () => {\n //return Math.round(Math.max(300, appPhotosManager.windowH / 1.5));\n return 300;\n };\n\n window.addEventListener('resize', () => {\n this.scrollable.onScrollOffset = getScrollOffset();\n });\n\n this.scrollable = new Scrollable(this.bubblesContainer, 'y', 'IM', this.chatInner, getScrollOffset()); */\n\n this.scrollable.onAdditionalScroll = this.onScroll;\n this.scrollable.onScrolledTop = () => this.loadMoreHistory(true);\n this.scrollable.onScrolledBottom = () => this.loadMoreHistory(false);\n // this.scrollable.attachSentinels(undefined, 300);\n\n if(IS_TOUCH_SUPPORTED && false) {\n this.scrollable.container.addEventListener('touchmove', () => {\n if(this.isScrollingTimeout) {\n clearTimeout(this.isScrollingTimeout);\n } else if(!this.chatInner.classList.contains('is-scrolling')) {\n this.chatInner.classList.add('is-scrolling');\n }\n }, {passive: true});\n\n this.scrollable.container.addEventListener('touchend', () => {\n if(!this.chatInner.classList.contains('is-scrolling')) {\n return;\n }\n\n if(this.isScrollingTimeout) {\n clearTimeout(this.isScrollingTimeout);\n }\n\n this.isScrollingTimeout = window.setTimeout(() => {\n this.chatInner.classList.remove('is-scrolling');\n this.isScrollingTimeout = 0;\n }, 1350);\n }, {passive: true});\n }\n }\n\n public async updateUnreadByDialog() {\n const historyStorage = await this.chat.getHistoryStorage();\n const maxId = this.peerId === rootScope.myId ? historyStorage.readMaxId : historyStorage.readOutboxMaxId;\n\n // /////this.log('updateUnreadByDialog', maxId, dialog, this.unreadOut);\n\n for(const msgId of this.unreadOut) {\n if(msgId > 0 && msgId <= maxId) {\n const bubble = this.bubbles[msgId];\n if(bubble) {\n this.unreadOut.delete(msgId);\n\n if(bubble.classList.contains('is-outgoing') || bubble.classList.contains('is-error')) {\n continue;\n }\n\n bubble.classList.remove('is-sent', 'is-sending', 'is-outgoing'); // is-sending can be when there are bulk of updates (e.g. sending command to Stickers bot)\n bubble.classList.add('is-read');\n }\n }\n }\n }\n\n public destroyBubble(bubble: HTMLElement, mid = +bubble.dataset.mid) {\n // this.log.warn('destroy bubble', bubble, mid);\n bubble.middlewareHelper.destroy();\n\n /* const mounted = this.getMountedBubble(mid);\n if(!mounted) return; */\n\n if(this.bubbles[mid] === bubble) { // have to check because can clear bubble with same id later\n delete this.bubbles[mid];\n }\n\n this.skippedMids.delete(mid);\n\n if(this.firstUnreadBubble === bubble) {\n this.firstUnreadBubble = null;\n }\n\n this.bubbleGroups.removeAndUnmountBubble(bubble);\n if(this.observer) {\n this.observer.unobserve(bubble, this.unreadedObserverCallback);\n this.unreaded.delete(bubble);\n\n this.observer.unobserve(bubble, this.viewsObserverCallback);\n this.viewsMids.delete(mid);\n\n this.observer.unobserve(bubble, this.stickerEffectObserverCallback);\n }\n\n // this.reactions.delete(mid);\n }\n\n public deleteMessagesByIds(mids: number[], permanent = true, ignoreOnScroll?: boolean) {\n let deleted = false;\n mids.forEach((mid) => {\n const bubble = this.bubbles[mid];\n if(!bubble) return;\n\n this.destroyBubble(bubble, mid);\n\n deleted = true;\n });\n\n if(!deleted) {\n return;\n }\n\n this.scrollable.ignoreNextScrollEvent();\n if(permanent && this.chat.selection.isSelecting) {\n this.chat.selection.deleteSelectedMids(this.peerId, mids);\n }\n\n animationIntersector.checkAnimations(false, this.chat.animationGroup);\n this.deleteEmptyDateGroups();\n\n if(!ignoreOnScroll) {\n this.scrollable.onScroll();\n // this.onScroll();\n }\n }\n\n private pollExtendedMediaMessages() {\n const mids = Array.from(this.extendedMediaMessages);\n return this.managers.appMessagesManager.getExtendedMedia(this.peerId, mids);\n }\n\n private setExtendedMediaMessagesPollInterval() {\n if(this.pollExtendedMediaMessagesPromise || !this.extendedMediaMessages.size) {\n return;\n }\n\n this.pollExtendedMediaMessagesPromise = pause(30000)\n .then(() => this.pollExtendedMediaMessages())\n .then(() => this.setExtendedMediaMessagesPollInterval());\n }\n\n private setTopPadding(middleware = this.getMiddleware()) {\n let isPaddingNeeded = false;\n let setPaddingTo: HTMLElement;\n if(!this.isTopPaddingSet && this.chat.type !== 'scheduled') {\n const {clientHeight, scrollHeight} = this.scrollable.container;\n isPaddingNeeded = clientHeight === scrollHeight;\n /* const firstEl = this.chatInner.firstElementChild as HTMLElement;\n if(this.chatInner.firstElementChild) {\n const visibleRect = getVisibleRect(firstEl, this.scrollable.container);\n isPaddingNeeded = !visibleRect.overflow.top && (visibleRect.rect.top - firstEl.offsetTop) !== this.scrollable.container.getBoundingClientRect().top;\n } else {\n isPaddingNeeded = true;\n } */\n\n if(isPaddingNeeded) {\n /* const add = clientHeight - scrollHeight;\n this.chatInner.style.paddingTop = add + 'px';\n this.scrollable.scrollTop += add; */\n setPaddingTo = this.chatInner;\n setPaddingTo.style.paddingTop = clientHeight + 'px';\n this.scrollable.setScrollTopSilently(scrollHeight);\n this.isTopPaddingSet = true;\n }\n }\n\n return {\n isPaddingNeeded,\n unsetPadding: isPaddingNeeded ? () => {\n if(middleware() && isPaddingNeeded) {\n setPaddingTo.style.paddingTop = '';\n this.isTopPaddingSet = false;\n }\n } : undefined\n };\n }\n\n private renderNewMessage(message: MyMessage, scrolledDown?: boolean) {\n const promise = this._renderNewMessage(message, scrolledDown);\n this.renderNewPromises.add(promise);\n promise.catch(noop).finally(() => {\n this.renderNewPromises.delete(promise);\n });\n return promise;\n }\n\n private async _renderNewMessage(message: MyMessage, scrolledDown?: boolean) {\n if(!this.scrollable.loadedAll.bottom) { // seems search active or sliced\n // this.log('renderNewMessagesByIds: seems search is active, skipping render:', mids);\n const setPeerPromise = this.chat.setPeerPromise;\n if(setPeerPromise) {\n const middleware = this.getMiddleware();\n setPeerPromise.then(async() => {\n if(!middleware()) return;\n const newMessage = await this.chat.getMessage(message.mid);\n if(!middleware()) return;\n this.renderNewMessage(newMessage);\n });\n }\n\n return;\n }\n\n if(this.chat.threadId && getMessageThreadId(message, this.chat.isForum) !== this.chat.threadId) {\n return;\n }\n\n if(this.bubbles[message.mid]) {\n return;\n }\n // ! should scroll even without new messages\n /* if(!mids.length) {\n return;\n } */\n\n if(!scrolledDown) {\n scrolledDown = this.scrolledDown && (\n !this.scrollingToBubble ||\n this.scrollingToBubble === this.getLastBubble() ||\n this.scrollingToBubble === this.chatInner\n );\n }\n\n const middleware = this.getMiddleware();\n const {isPaddingNeeded, unsetPadding} = this.setTopPadding(middleware);\n\n const promise = this.performHistoryResult({history: [message]}, false);\n if(scrolledDown) {\n promise.then(() => {\n if(!middleware()) return;\n // this.log('renderNewMessagesByIDs: messagesQueuePromise after', this.scrollable.isScrolledDown);\n // this.scrollable.scrollTo(this.scrollable.scrollHeight, 'top', true, true, 5000);\n // const bubble = this.bubbles[Math.max(...mids)];\n\n let bubble: HTMLElement;\n if(this.chat.type === 'scheduled') {\n bubble = this.bubbles[message.mid];\n }\n\n const promise = bubble ? this.scrollToBubbleEnd(bubble) : this.scrollToEnd();\n if(isPaddingNeeded) {\n // it will be called only once even if was set multiple times (that won't happen)\n promise.then(unsetPadding);\n }\n\n // this.scrollable.scrollIntoViewNew(this.chatInner, 'end');\n\n /* setTimeout(() => {\n this.log('messagesQueuePromise afterafter:', this.chatInner.childElementCount, this.scrollable.scrollHeight);\n }, 10); */\n });\n }\n\n return promise;\n }\n\n public getLastBubble() {\n const group = this.bubbleGroups.getLastGroup();\n return group?.lastItem?.bubble;\n }\n\n public scrollToBubble(\n element: HTMLElement,\n position: ScrollLogicalPosition,\n forceDirection?: FocusDirection,\n forceDuration?: number\n ) {\n const bubble = findUpClassName(element, 'bubble');\n\n if(!element.parentElement) {\n this.log.error('element is not connected', bubble);\n }\n\n let fallbackToElementStartWhenCentering: HTMLElement;\n // * if it's a start, then scroll to start of the group\n if(bubble && position !== 'end') {\n const item = this.bubbleGroups.getItemByBubble(bubble);\n if(item && item.group.firstItem === item && whichChild(item.group.container) === (this.stickyIntersector ? STICKY_OFFSET : 1)) {\n const dateGroup = item.group.container.parentElement;\n // if(whichChild(dateGroup) === 0) {\n fallbackToElementStartWhenCentering = dateGroup;\n // position = 'start';\n // element = dateGroup;\n // }\n }\n }\n\n // const isLastBubble = this.getLastBubble() === bubble;\n /* if(isLastBubble) {\n element = this.getLastDateGroup();\n } */\n\n const margin = 4; // * 4 = .25rem\n /* if(isLastBubble && this.chat.type === 'chat' && this.bubblesContainer.classList.contains('is-chat-input-hidden')) {\n margin = 20;\n } */\n\n const isChangingHeight = (this.chat.input.messageInput && this.chat.input.messageInput.classList.contains('is-changing-height')) || this.chat.container.classList.contains('is-toggling-helper');\n const promise = this.scrollable.scrollIntoViewNew({\n element,\n position,\n margin,\n forceDirection,\n forceDuration,\n axis: 'y',\n getNormalSize: isChangingHeight ? ({rect}) => {\n // return rect.height;\n\n let height = windowSize.height;\n // height -= this.chat.topbar.container.getBoundingClientRect().height;\n height -= this.container.offsetTop;\n height -= mediaSizes.isMobile || windowSize.height < 570 ? 58 : 78;\n return height;\n\n /* const rowsWrapperHeight = this.chat.input.rowsWrapper.getBoundingClientRect().height;\n const diff = rowsWrapperHeight - 54;\n return rect.height + diff; */\n } : undefined,\n fallbackToElementStartWhenCentering,\n startCallback: (dimensions) => {\n // this.onScroll(true, this.scrolledDown && dimensions.distanceToEnd <= SCROLLED_DOWN_THRESHOLD ? undefined : dimensions);\n this.onScroll(true, dimensions);\n\n if(this.updateGradient) {\n const {gradientRenderer} = this.chat;\n gradientRenderer?.toNextPosition(dimensions.getProgress);\n this.updateGradient = undefined;\n }\n }\n });\n\n // fix flickering date when opening unread chat and focusing message\n if(forceDirection === FocusDirection.Static) {\n this.scrollable.lastScrollPosition = this.scrollable.scrollTop;\n }\n\n return promise;\n }\n\n public scrollToEnd() {\n return this.scrollToBubbleEnd(this.chatInner);\n }\n\n public async scrollToBubbleEnd(bubble: HTMLElement) {\n /* if(DEBUG) {\n this.log('scrollToNewLastBubble: will scroll into view:', bubble);\n } */\n\n if(bubble) {\n this.scrollingToBubble = bubble;\n const middleware = this.getMiddleware();\n await this.scrollToBubble(bubble, 'end', undefined, undefined);\n if(!middleware()) return;\n this.scrollingToBubble = undefined;\n }\n }\n\n // ! can't get it by chatInner.lastElementChild because placeholder can be the last...\n // private getLastDateGroup() {\n // let lastTime = 0, lastElem: HTMLElement;\n // for(const i in this.dateMessages) {\n // const dateMessage = this.dateMessages[i];\n // if(dateMessage.firstTimestamp > lastTime) {\n // lastElem = dateMessage.container;\n // lastTime = dateMessage.firstTimestamp;\n // }\n // }\n\n // return lastElem;\n // }\n\n public async scrollToBubbleIfLast(bubble: HTMLElement) {\n if(this.getLastBubble() === bubble) {\n // return this.scrollToBubbleEnd(bubble);\n return this.scrollToEnd();\n }\n }\n\n public highlightBubble(element: HTMLElement) {\n const datasetKey = 'highlightTimeout';\n if(element.dataset[datasetKey]) {\n clearTimeout(+element.dataset[datasetKey]);\n element.classList.remove('is-highlighted');\n void element.offsetWidth; // reflow\n }\n\n element.classList.add('is-highlighted');\n element.dataset[datasetKey] = '' + setTimeout(() => {\n element.classList.remove('is-highlighted');\n delete element.dataset[datasetKey];\n }, 2000);\n }\n\n private createDateBubble(timestamp: number, date: Date = new Date(timestamp * 1000)) {\n let dateElement: HTMLElement;\n\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n\n const isScheduled = this.chat.type === 'scheduled';\n\n if(today.getTime() === date.getTime()) {\n dateElement = i18n(isScheduled ? 'Chat.Date.ScheduledForToday' : 'Date.Today');\n } else if(isScheduled && timestamp === SEND_WHEN_ONLINE_TIMESTAMP) {\n dateElement = i18n('MessageScheduledUntilOnline');\n } else {\n const options: Intl.DateTimeFormatOptions = {\n day: 'numeric',\n month: 'long'\n };\n\n if(date.getFullYear() !== today.getFullYear()) {\n options.year = 'numeric';\n }\n\n dateElement = new I18n.IntlDateElement({\n date,\n options\n }).element;\n\n if(isScheduled) {\n dateElement = i18n('Chat.Date.ScheduledFor', [dateElement]);\n }\n }\n\n const bubble = document.createElement('div');\n bubble.className = 'bubble service is-date';\n const bubbleContent = document.createElement('div');\n bubbleContent.classList.add('bubble-content');\n const serviceMsg = document.createElement('div');\n serviceMsg.classList.add('service-msg');\n\n serviceMsg.append(dateElement);\n\n bubbleContent.append(serviceMsg);\n bubble.append(bubbleContent);\n\n return bubble;\n }\n\n public getDateForDateContainer(timestamp: number) {\n const date = new Date(timestamp * 1000);\n date.setHours(0, 0, 0);\n return {date, dateTimestamp: date.getTime()};\n }\n\n public getDateContainerByTimestamp(timestamp: number) {\n const {date, dateTimestamp} = this.getDateForDateContainer(timestamp);\n let ret = this.dateMessages[dateTimestamp];\n if(ret) {\n return ret;\n }\n\n const bubble = this.createDateBubble(timestamp, date);\n // bubble.classList.add('is-sticky');\n const fakeBubble = this.createDateBubble(timestamp, date);\n fakeBubble.classList.add('is-fake');\n\n const container = document.createElement('section');\n container.className = 'bubbles-date-group';\n container.append(bubble, fakeBubble);\n\n ret = this.dateMessages[dateTimestamp] = {\n div: bubble,\n container,\n firstTimestamp: date.getTime()\n };\n\n const haveTimestamps = getObjectKeysAndSort(this.dateMessages, 'asc');\n const length = haveTimestamps.length;\n let i = 0, insertBefore: HTMLElement; // there can be 'first bubble' (e.g. bot description) so can't insert by index\n for(; i < haveTimestamps.length; ++i) {\n const t = haveTimestamps[i];\n insertBefore = this.dateMessages[t].container;\n if(dateTimestamp < t) {\n break;\n }\n }\n\n if(i === length && insertBefore) {\n insertBefore = insertBefore.nextElementSibling as HTMLElement;\n }\n\n if(!insertBefore) {\n this.chatInner.append(container);\n } else {\n this.chatInner.insertBefore(container, insertBefore);\n }\n\n this.stickyIntersector?.observeStickyHeaderChanges(container);\n\n if(this.chatInner.parentElement) {\n this.container.classList.add('has-groups');\n }\n\n return ret;\n }\n\n private destroyScrollable() {\n this.scrollable.destroy();\n }\n\n public destroy() {\n // this.chat.log.error('Bubbles destroying');\n\n this.destroyScrollable();\n\n this.listenerSetter.removeAll();\n\n this.lazyLoadQueue.clear();\n this.observer && this.observer.disconnect();\n this.stickyIntersector && this.stickyIntersector.disconnect();\n\n delete this.lazyLoadQueue;\n this.observer && delete this.observer;\n this.stickyIntersector && delete this.stickyIntersector;\n }\n\n public cleanup(bubblesToo = false) {\n this.log('cleanup');\n\n this.bubbles = {}; // clean it before so sponsored message won't be deleted faster on peer changing\n // //console.time('appImManager cleanup');\n this.setLoaded('top', false, false);\n this.setLoaded('bottom', false, false);\n\n // cancel scroll\n cancelAnimationByKey(this.scrollable.container);\n\n // do not wait ending of previous scale animation\n interruptHeavyAnimation();\n\n if(TEST_SCROLL !== undefined) {\n TEST_SCROLL = TEST_SCROLL_TIMES;\n }\n\n this.skippedMids.clear();\n this.dateMessages = {};\n this.bubbleGroups.cleanup();\n this.unreadOut.clear();\n this.needUpdate.length = 0;\n this.lazyLoadQueue.clear();\n this.renderNewPromises.clear();\n\n // clear messages\n if(bubblesToo) {\n this.scrollable.container.textContent = '';\n this.chatInner.textContent = '';\n this.cleanupPlaceholders();\n }\n\n this.firstUnreadBubble = null;\n this.attachedUnreadBubble = false;\n\n this.batchProcessor.clear();\n\n this.getHistoryTopPromise = this.getHistoryBottomPromise = undefined;\n this.fetchNewPromise = undefined;\n this.getSponsoredMessagePromise = undefined;\n this.updateGradient = undefined;\n\n if(this.stickyIntersector) {\n this.stickyIntersector.disconnect();\n }\n\n if(this.observer) {\n this.observer.disconnect();\n\n this.unreaded.clear();\n this.unreadedSeen.clear();\n this.readPromise = undefined;\n\n this.viewsMids.clear();\n }\n\n this.middlewareHelper.clean();\n\n this.onAnimateLadder = undefined;\n this.resolveLadderAnimation = undefined;\n this.attachPlaceholderOnRender = undefined;\n this.emptyPlaceholderBubble = undefined;\n this.sponsoredMessage = undefined;\n this.previousStickyDate = undefined;\n\n this.scrollingToBubble = undefined;\n // //console.timeEnd('appImManager cleanup');\n\n this.isTopPaddingSet = false;\n\n this.renderingMessages.clear();\n this.bubblesToEject.clear();\n this.bubblesToReplace.clear();\n\n // this.reactions.clear();\n\n if(this.isScrollingTimeout) {\n clearTimeout(this.isScrollingTimeout);\n this.isScrollingTimeout = 0;\n }\n\n this.container.classList.remove('has-sticky-dates');\n this.scrollable.cancelMeasure();\n }\n\n private cleanupPlaceholders(bubble = this.emptyPlaceholderBubble) {\n if(bubble) {\n this.destroyBubble(bubble);\n }\n }\n\n public async setPeer(options: ChatSetPeerOptions & {samePeer: boolean}): Promise<{cached?: boolean, promise: Chat['setPeerPromise']}> {\n const {samePeer, peerId, stack} = options;\n let {lastMsgId, startParam} = options;\n const tempId = ++this.setPeerTempId;\n\n if(!peerId) {\n this.cleanup(true);\n this.preloader.detach();\n return null;\n }\n\n const perf = performance.now();\n const log = this.log.bindPrefix('setPeer');\n log.warn('start');\n\n const middleware = () => {\n return this.setPeerTempId === tempId;\n };\n\n const m = middlewarePromise(middleware, PEER_CHANGED_ERROR);\n\n if(!samePeer) {\n await m(this.chat.onChangePeer(options, m));\n }\n\n /* if(samePeer && this.chat.setPeerPromise) {\n return {cached: true, promise: this.chat.setPeerPromise};\n } */\n\n const chatType = this.chat.type;\n\n if(chatType === 'scheduled' || this.chat.isRestricted) {\n lastMsgId = 0;\n }\n\n const historyStorage = await m(this.chat.getHistoryStorage());\n const topMessage = chatType === 'pinned' ? await m(this.managers.appMessagesManager.getPinnedMessagesMaxId(peerId, this.chat.threadId)) : historyStorage.maxId ?? 0;\n const isTarget = lastMsgId !== undefined;\n\n // * this one will fix topMessage for null message in history (e.g. channel comments with only 1 comment and it is a topMessage)\n /* if(chatType !== 'pinned' && topMessage && !historyStorage.history.slice.includes(topMessage)) {\n topMessage = 0;\n } */\n\n let followingUnread: boolean;\n let readMaxId = 0, savedPosition: ReturnType<AppImManager['getChatSavedPosition']>, overrideAdditionMsgId: number;\n if(!isTarget) {\n if(!samePeer) {\n savedPosition = this.chat.appImManager.getChatSavedPosition(this.chat);\n }\n\n if(savedPosition) {\n\n } else if(topMessage) {\n readMaxId = await m(this.managers.appMessagesManager.getReadMaxIdIfUnread(peerId, this.chat.threadId));\n const dialog = await m(this.chat.getDialogOrTopic());\n if(/* dialog.unread_count */readMaxId && !samePeer && (!dialog || dialog.unread_count !== 1)) {\n const foundSlice = historyStorage.history.findSliceOffset(readMaxId);\n if(foundSlice && foundSlice.slice.isEnd(SliceEnd.Bottom)) {\n overrideAdditionMsgId = foundSlice.slice[foundSlice.offset - 25] || foundSlice.slice[0] || readMaxId;\n }\n\n followingUnread = !isTarget;\n lastMsgId = readMaxId;\n } else {\n lastMsgId = topMessage;\n // lastMsgID = topMessage;\n }\n }\n }\n\n const isJump = lastMsgId !== topMessage/* && overrideAdditionMsgId === undefined */;\n\n if(startParam === undefined && await m(this.chat.isStartButtonNeeded())) {\n startParam = BOT_START_PARAM;\n }\n\n if(samePeer) {\n if(stack && lastMsgId) {\n this.followStack.push(stack);\n }\n\n const mounted = await m(this.getMountedBubble(lastMsgId));\n if(mounted) {\n if(isTarget) {\n this.scrollToBubble(mounted.bubble, 'center');\n this.highlightBubble(mounted.bubble);\n this.chat.dispatchEvent('setPeer', lastMsgId, false);\n } else if(topMessage && !isJump) {\n // log('will scroll down', this.scroll.scrollTop, this.scroll.scrollHeight);\n // scrollable.setScrollTopSilently(scrollable.scrollHeight);\n this.scrollToEnd();\n this.chat.dispatchEvent('setPeer', lastMsgId, true);\n }\n\n if(startParam !== undefined) {\n this.chat.input.setStartParam(startParam);\n }\n\n if(options.mediaTimestamp) {\n getHeavyAnimationPromise().then(() => {\n this.playMediaWithTimestampAndMid({\n lastMsgId,\n middleware,\n mediaTimestamp: options.mediaTimestamp\n });\n });\n }\n\n return null;\n }\n } else {\n if(this.peerId) { // * set new queue id if new peer (setting not from 0)\n this.lazyLoadQueue.queueId = ++queueId;\n this.managers.apiFileManager.setQueueId(this.chat.bubbles.lazyLoadQueue.queueId);\n }\n\n this.followStack.length = 0;\n\n this.passEntities = {\n messageEntityBotCommand: await m(this.managers.appPeersManager.isAnyGroup(peerId)) || this.chat.isBot\n };\n }\n\n if(DEBUG) {\n log('setPeer peerId:', peerId, historyStorage, lastMsgId, topMessage);\n }\n\n // add last message, bc in getHistory will load < max_id\n const additionMsgId = overrideAdditionMsgId ?? (isJump || chatType === 'scheduled' || this.chat.isRestricted ? 0 : topMessage);\n\n let maxBubbleId = 0;\n if(samePeer) {\n const el = this.getBubbleByPoint('bottom'); // ! this may not work if being called when chat is hidden\n // this.chat.log('[PM]: setCorrectIndex: get last element perf:', performance.now() - perf, el);\n if(el) {\n maxBubbleId = +el.dataset.mid;\n }\n\n if(maxBubbleId <= 0) {\n maxBubbleId = Math.max(...Object.keys(this.bubbles).map((mid) => +mid));\n }\n } else {\n this.isFirstLoad = true;\n this.destroyResizeObserver();\n }\n\n const oldChatInner = this.chatInner;\n const oldPlaceholderBubble = this.emptyPlaceholderBubble;\n this.cleanup();\n const chatInner = this.chatInner = document.createElement('div');\n if(samePeer) {\n chatInner.className = oldChatInner.className;\n chatInner.classList.remove('disable-hover', 'is-scrolling');\n } else {\n chatInner.classList.add('bubbles-inner');\n }\n\n this.lazyLoadQueue.lock();\n\n // const haveToScrollToBubble = (topMessage && (isJump || samePeer)) || isTarget;\n const haveToScrollToBubble = samePeer || (topMessage && isJump) || isTarget;\n const fromUp = maxBubbleId > 0 && (!lastMsgId || maxBubbleId < lastMsgId || lastMsgId < 0);\n const scrollFromDown = !fromUp && samePeer;\n const scrollFromUp = !scrollFromDown && fromUp/* && (samePeer || forwardingUnread) */;\n this.willScrollOnLoad = scrollFromDown || scrollFromUp;\n\n this.setPeerOptions = {\n lastMsgId,\n topMessage,\n savedPosition\n };\n\n if(!samePeer) {\n this.ranks = undefined;\n this.processRanks = undefined;\n this.canShowRanks = false;\n\n if(this.chat.isChannel) {\n this.canShowRanks = true;\n const processRanks = this.processRanks = new Set();\n\n const promise = this.managers.acknowledged.appProfileManager.getParticipants(this.peerId.toChatId(), {_: 'channelParticipantsAdmins'}, 100);\n const ackedResult = await m(promise);\n const setRanksPromise = ackedResult.result.then((channelParticipants) => {\n if(this.processRanks !== processRanks) {\n return;\n }\n\n const participants = channelParticipants.participants as (ChatParticipant.chatParticipantAdmin | ChannelParticipant.channelParticipantAdmin)[];\n this.ranks = new Map();\n participants.forEach((participant) => {\n const rank = getParticipantRank(participant);\n this.ranks.set(participant.user_id.toPeerId(), rank);\n });\n\n getHeavyAnimationPromise().then(() => {\n if(this.processRanks !== processRanks) {\n return;\n }\n\n processRanks.forEach((callback) => callback());\n this.processRanks = undefined;\n });\n }, (err) => {\n if((err as ApiError).type !== 'CHAT_ADMIN_REQUIRED') {\n this.log.error('ranks error', err);\n }\n\n this.ranks = new Map();\n });\n\n if(ackedResult.cached) {\n await m(setRanksPromise);\n }\n }\n }\n\n let result: Awaited<ReturnType<ChatBubbles['getHistory']>>;\n if(!savedPosition) {\n result = await m(this.getHistory1(lastMsgId, true, isJump, additionMsgId));\n } else {\n result = {\n promise: getHeavyAnimationPromise().then(() => {\n return this.performHistoryResult({history: savedPosition.mids}, true);\n }) as any,\n cached: true,\n waitPromise: Promise.resolve()\n };\n }\n\n this.setPeerCached = result.cached;\n\n log.warn('got history');// warning\n\n const {promise, cached} = result;\n const finishPeerChangeOptions: Parameters<Chat['finishPeerChange']>[0] = {\n isTarget,\n isJump,\n lastMsgId,\n startParam,\n middleware\n };\n\n if(!cached && !samePeer) {\n await m(this.chat.finishPeerChange(finishPeerChangeOptions));\n this.scrollable.container.replaceChildren();\n // oldContainer.textContent = '';\n // oldChatInner.remove();\n this.preloader.attach(this.container);\n }\n\n /* this.ladderDeferred && this.ladderDeferred.resolve();\n this.ladderDeferred = deferredPromise<void>(); */\n\n animationIntersector.lockGroup(this.chat.animationGroup);\n const setPeerPromise = m(promise).then(async() => {\n log.warn('promise fulfilled');\n\n const mountedByLastMsgId = haveToScrollToBubble ? await m(lastMsgId ? this.getMountedBubble(lastMsgId) : {bubble: this.getLastBubble()}) : undefined;\n if(cached && !samePeer) {\n log.warn('finishing peer change');\n await m(this.chat.finishPeerChange(finishPeerChangeOptions)); // * костыль\n log.warn('finished peer change');\n }\n\n this.preloader.detach();\n\n if(this.resolveLadderAnimation) {\n this.resolveLadderAnimation();\n this.resolveLadderAnimation = undefined;\n }\n\n this.setPeerCached = undefined;\n\n // this.ladderDeferred.resolve();\n\n const scrollable = this.scrollable;\n scrollable.lastScrollDirection = 0;\n scrollable.lastScrollPosition = 0;\n replaceContent(scrollable.container, chatInner);\n // this.chat.topbar.container.nextElementSibling.replaceWith(container);\n\n if(oldPlaceholderBubble) {\n this.cleanupPlaceholders(oldPlaceholderBubble);\n }\n\n if(this.attachPlaceholderOnRender) {\n this.attachPlaceholderOnRender();\n }\n\n if(!isTarget && this.chat.isPinnedMessagesNeeded()) {\n this.chat.topbar.pinnedMessage?.setCorrectIndex(0);\n }\n\n this.container.classList.toggle('has-groups', !!Object.keys(this.dateMessages).length);\n\n log.warn('mounted chat', this.chatInner === chatInner, this.chatInner.parentElement, performance.now() - perf);\n\n animationIntersector.unlockGroup(this.chat.animationGroup);\n animationIntersector.checkAnimations(false, this.chat.animationGroup/* , true */);\n\n // fastRaf(() => {\n this.lazyLoadQueue.unlock();\n // });\n\n // if(dialog && lastMsgID && lastMsgID !== topMessage && (this.bubbles[lastMsgID] || this.firstUnreadBubble)) {\n if(savedPosition) {\n scrollable.setScrollTopSilently(savedPosition.top);\n /* const mountedByLastMsgId = this.getMountedBubble(lastMsgId);\n let bubble: HTMLElement = mountedByLastMsgId?.bubble;\n if(!bubble?.parentElement) {\n bubble = this.findNextMountedBubbleByMsgId(lastMsgId);\n }\n\n if(bubble) {\n const top = bubble.getBoundingClientRect().top;\n const distance = savedPosition.top - top;\n scrollable.scrollTop += distance;\n } */\n } else if(haveToScrollToBubble) {\n let unsetPadding: () => void;\n if(scrollFromDown) {\n scrollable.setScrollTopSilently(99999);\n } else if(scrollFromUp) {\n const set = this.setTopPadding();\n if(set.isPaddingNeeded) {\n unsetPadding = set.unsetPadding;\n }\n\n scrollable.setScrollTopSilently(0);\n }\n\n // const mountedByLastMsgId = lastMsgId ? this.getMountedBubble(lastMsgId) : {bubble: this.getLastBubble()};\n let bubble: HTMLElement = (followingUnread && this.firstUnreadBubble) || mountedByLastMsgId?.bubble;\n if(!bubble?.parentElement) {\n bubble = this.findNextMountedBubbleByMsgId(lastMsgId, false) || this.findNextMountedBubbleByMsgId(lastMsgId, true);\n }\n\n let promise: Promise<void>;\n // ! sometimes there can be no bubble\n if(bubble) {\n const lastBubble = this.getLastBubble();\n const position: ScrollLogicalPosition = followingUnread ? 'start' : (!isJump && !isTarget && lastBubble === bubble ? 'end' : 'center');\n\n if(position === 'end' && lastBubble === bubble && samePeer) {\n promise = this.scrollToEnd();\n } else {\n promise = this.scrollToBubble(bubble, position, !samePeer ? FocusDirection.Static : undefined);\n }\n\n if(!followingUnread && isTarget) {\n this.highlightBubble(bubble);\n }\n }\n\n if(unsetPadding) {\n (promise || Promise.resolve()).then(() => {\n unsetPadding();\n });\n }\n } else {\n scrollable.setScrollTopSilently(99999);\n }\n\n // if(!cached) {\n this.onRenderScrollSet();\n // }\n\n this.onScroll();\n\n const afterSetPromise = Promise.all([\n setPeerPromise,\n getHeavyAnimationPromise()\n ]);\n afterSetPromise.then(() => { // check whether list isn't full\n if(!middleware()) {\n return;\n }\n\n scrollable.checkForTriggers();\n\n if(options.mediaTimestamp !== undefined) {\n // ! :(\n const p = cached && !samePeer && liteMode.isAvailable('animations') && this.chat.appImManager.chats.length > 1 ?\n pause(400) :\n Promise.resolve();\n p.then(() => {\n return this.playMediaWithTimestampAndMid({\n lastMsgId,\n middleware,\n mediaTimestamp: options.mediaTimestamp\n });\n });\n }\n\n // if(cached) {\n // this.onRenderScrollSet();\n // }\n });\n\n this.chat.dispatchEvent('setPeer', lastMsgId, !isJump);\n\n Promise.all([\n this.setFetchReactionsInterval(afterSetPromise),\n this.setFetchHistoryInterval({\n afterSetPromise,\n lastMsgId,\n samePeer,\n savedPosition,\n topMessage\n })\n ]).then(() => {\n log('scrolledAllDown:', scrollable.loadedAll.bottom);\n // if(!this.unreaded.length && dialog) { // lol\n if(scrollable.loadedAll.bottom && topMessage && !this.unreaded.size) { // lol\n this.onScrolledAllDown();\n }\n });\n\n if(chatType === 'chat' && !this.chat.isForumTopic) {\n const dialog = await m(this.managers.appMessagesManager.getDialogOnly(peerId));\n if(dialog?.pFlags.unread_mark) {\n this.managers.appMessagesManager.markDialogUnread(peerId, true);\n }\n }\n\n // this.chatInner.classList.remove('disable-hover', 'is-scrolling'); // warning, performance!\n }).catch((err) => {\n log.error('setPeer promise error:', err);\n if(!middleware()) {\n this.preloader.detach();\n }\n\n throw err;\n });\n\n return {cached, promise: setPeerPromise};\n }\n\n public playMediaWithTimestampAndMid({\n middleware,\n lastMsgId,\n mediaTimestamp\n }: {\n middleware: () => boolean,\n lastMsgId: number,\n mediaTimestamp: number\n }) {\n this.getMountedBubble(lastMsgId).then((mounted) => {\n if(!middleware() || !mounted) {\n return;\n }\n\n this.playMediaWithTimestamp(mounted.bubble, mediaTimestamp);\n });\n }\n\n public playMediaWithTimestamp(element: HTMLElement, timestamp: number) {\n const bubble = findUpClassName(element, 'bubble');\n const groupedItem = findUpClassName(element, 'grouped-item');\n const albumItemMid = groupedItem ? +groupedItem.dataset.mid : +bubble.dataset.textMid;\n let attachment = bubble.querySelector<HTMLElement>('.attachment');\n if(attachment) {\n if(albumItemMid) {\n attachment = attachment.querySelector(`[data-mid=\"${albumItemMid}\"]`);\n }\n\n const media = attachment.querySelector<HTMLElement>('img, video, canvas');\n this.checkTargetForMediaViewer(media, undefined, timestamp);\n return;\n }\n\n const audio = (groupedItem || bubble).querySelector<AudioElement>('.audio');\n if(audio) {\n audio.playWithTimestamp(timestamp);\n return;\n }\n\n const replyToPeerId = bubble.dataset.replyToPeerId.toPeerId();\n const replyToMid = +bubble.dataset.replyToMid;\n if(replyToPeerId && replyToMid) {\n if(replyToPeerId === this.peerId) {\n this.chat.setMessageId(replyToMid, timestamp);\n } else {\n this.chat.appImManager.setInnerPeer({\n peerId: replyToPeerId,\n mediaTimestamp: timestamp\n });\n }\n }\n }\n\n private async setFetchReactionsInterval(afterSetPromise: Promise<any>) {\n const middleware = this.getMiddleware();\n const needReactionsInterval = this.chat.isChannel;\n if(needReactionsInterval) {\n const fetchReactions = async() => {\n if(!middleware()) return;\n\n const mids: number[] = [];\n for(const mid in this.bubbles) {\n let message = await this.chat.getMessage(+mid);\n if(message?._ !== 'message') {\n continue;\n }\n\n message = await this.managers.appMessagesManager.getGroupsFirstMessage(message);\n mids.push(message.mid);\n }\n\n const promise = mids.length ? this.managers.appReactionsManager.getMessagesReactions(this.peerId, mids) : Promise.resolve();\n promise.then(() => {\n setTimeout(fetchReactions, 10e3);\n });\n };\n\n Promise.all([afterSetPromise, getHeavyAnimationPromise(), pause(500)]).then(() => {\n fetchReactions();\n });\n }\n }\n\n private async setFetchHistoryInterval({\n lastMsgId,\n topMessage,\n afterSetPromise,\n savedPosition,\n samePeer\n }: {\n lastMsgId: number,\n topMessage: number,\n afterSetPromise: Promise<any>,\n savedPosition: ChatSavedPosition,\n samePeer: boolean\n }) {\n const peerId = this.peerId;\n if(peerId.isUser()) {\n return;\n }\n\n const middleware = this.getMiddleware();\n const needFetchInterval = await this.managers.appMessagesManager.isFetchIntervalNeeded(peerId);\n const needFetchNew = savedPosition || needFetchInterval;\n if(!needFetchNew) {\n return;\n }\n\n await afterSetPromise;\n if(!middleware()) {\n return;\n }\n\n const chatId = peerId.toChatId();\n middleware.onClean(() => {\n this.managers.apiUpdatesManager.unsubscribeFromChannelUpdates(chatId);\n });\n\n this.managers.apiUpdatesManager.subscribeToChannelUpdates(chatId);\n return;\n\n this.setLoaded('bottom', false);\n this.scrollable.checkForTriggers();\n\n if(!needFetchInterval) {\n return;\n }\n\n const f = () => {\n this.fetchNewPromise = new Promise<void>(async(resolve) => {\n if(!middleware() || !(await this.managers.appMessagesManager.isFetchIntervalNeeded(peerId))) {\n resolve();\n return;\n }\n\n this.managers.appMessagesManager.getNewHistory(peerId, this.chat.threadId).then((result) => {\n if(!middleware() || !result) {\n resolve();\n return;\n }\n\n const {isBottomEnd} = result;\n if(this.scrollable.loadedAll.bottom && this.scrollable.loadedAll.bottom !== isBottomEnd) {\n this.setLoaded('bottom', isBottomEnd);\n this.onScroll();\n }\n\n setTimeout(f, 30e3);\n resolve();\n });\n }).finally(() => {\n this.fetchNewPromise = undefined;\n });\n };\n\n if(samePeer) {\n setTimeout(f, 30e3);\n } else {\n f();\n }\n }\n\n public async onScrolledAllDown() {\n if(this.chat.type === 'chat' || this.chat.type === 'discussion') {\n const historyMaxId = await this.chat.getHistoryMaxId();\n this.managers.appMessagesManager.readHistory(this.peerId, historyMaxId, this.chat.threadId, true);\n }\n }\n\n public async finishPeerChange() {\n const [isChannel, canWrite, isAnyGroup] = await Promise.all([\n this.chat.isChannel,\n this.chat.canSend(),\n this.chat.isAnyGroup\n ]);\n\n return () => {\n this.chatInner.classList.toggle('has-rights', canWrite);\n this.container.classList.toggle('is-chat-input-hidden', !canWrite);\n\n this.chatInner.classList.toggle('is-chat', isAnyGroup);\n this.chatInner.classList.toggle('is-channel', isChannel);\n\n this.createResizeObserver();\n };\n }\n\n private processBatch = async(...args: Parameters<ChatBubbles['batchProcessor']['process']>) => {\n let [loadQueue, m, log] = args;\n\n const filterQueue = (queue: typeof loadQueue) => {\n return queue.filter((details) => {\n // message can be deleted during rendering\n return details && this.bubbles[details.bubble.dataset.mid] === details.bubble;\n });\n };\n\n loadQueue = filterQueue(loadQueue);\n\n log('messages rendered');\n\n const reverse = loadQueue[0]?.reverse;\n\n const {groups, avatarPromises} = this.groupBubbles(loadQueue.filter((details) => details.updatePosition));\n\n // if(groups.length > 2 && loadQueue.length === 1) {\n // debugger;\n // }\n\n const promises = loadQueue.reduce((acc, details) => {\n const perf = performance.now();\n\n const promises = details.promises.slice();\n const timePromises = promises.map(async(promise) => (await promise, performance.now() - perf));\n Promise.all(timePromises).then((times) => {\n log.groupCollapsed('media message time', performance.now() - perf, details, times);\n times.forEach((time, idx) => {\n log('media message time', time, idx, promises[idx]);\n });\n log.groupEnd();\n });\n\n // if(details.updatePosition) {\n // if(res) {\n // groups.add(res.group);\n // if(details.needAvatar) {\n // details.promises.push(res.group.createAvatar(details.message));\n // }\n // }\n // }\n\n acc.push(...details.promises);\n return acc;\n }, [] as Promise<any>[]);\n\n promises.push(...avatarPromises);\n // promises.push(pause(200));\n\n // * это нужно для того, чтобы если захочет подгрузить reply или какое-либо сообщение, то скролл не прервался\n // * если добавить этот промис - в таком случае нужно сделать, чтобы скроллило к последнему сообщению после рендера\n // promises.push(getHeavyAnimationPromise());\n\n log('media promises to call', promises, loadQueue, this.isHeavyAnimationInProgress);\n await m(Promise.all([...promises, this.setUnreadDelimiter()]).catch(noop)); // не нашёл места лучше\n await m(fastRafPromise()); // have to be the last\n log('media promises end');\n\n loadQueue = filterQueue(loadQueue);\n\n const {restoreScroll, scrollSaver} = this.prepareToSaveScroll(reverse);\n // if(this.messagesQueueOnRender) {\n // this.messagesQueueOnRender();\n // }\n\n this.messagesQueueOnRenderAdditional?.();\n\n this.ejectBubbles();\n for(const [bubble, oldBubble] of this.bubblesToReplace) {\n if(scrollSaver) {\n scrollSaver.replaceSaved(oldBubble, bubble);\n }\n\n if(!loadQueue.find((details) => details.bubble === bubble)) {\n continue;\n }\n\n const item = this.bubbleGroups.getItemByBubble(bubble);\n if(!item) {\n this.log.error('NO ITEM BY BUBBLE', bubble);\n } else {\n item.mounted = false;\n if(!groups.includes(item.group)) {\n groups.push(item.group);\n }\n }\n\n this.bubblesToReplace.delete(bubble);\n }\n\n if(this.chat.selection.isSelecting) {\n loadQueue.forEach(({bubble}) => {\n this.chat.selection.toggleElementCheckbox(bubble, true);\n });\n }\n\n loadQueue.forEach(({message, bubble, updatePosition}) => {\n if(message.pFlags.local && updatePosition) {\n this.chatInner[(message as Message.message).pFlags.sponsored ? 'append' : 'prepend'](bubble);\n return;\n }\n });\n\n this.bubbleGroups.mountUnmountGroups(groups);\n // this.bubbleGroups.findIncorrentPositions();\n\n this.updatePlaceholderPosition?.();\n\n restoreScroll?.();\n\n m(pause(!this.chat.setPeerPromise ? 0 : 1000))\n .then(() => m(getHeavyAnimationPromise()))\n .then(() => {\n this.lazyLoadQueue.setAllSeen();\n }).catch(noop);\n\n // this.setStickyDateManually();\n };\n\n public renderMessagesQueue(options: ReturnType<ChatBubbles['safeRenderMessage']>) {\n return this.batchProcessor.addToQueue(options);\n }\n\n private ejectBubbles() {\n for(const bubble of this.bubblesToEject) {\n bubble.remove();\n // this.bubbleGroups.removeAndUnmountBubble(bubble);\n }\n\n this.bubblesToEject.clear();\n }\n\n public groupBubbles(items: Array<{\n // Awaited<ReturnType<ChatBubbles['safeRenderMessage']>> &\n bubble: HTMLElement,\n message: Message.message | Message.messageService\n }/* & {\n unmountIfFound?: boolean\n } */>) {\n let modifiedGroups: typeof groups;\n\n if(this.chat.type === 'scheduled') {\n modifiedGroups = new Set();\n items.forEach(({bubble, message}) => {\n const item = this.bubbleGroups.getItemByBubble(bubble);\n const group = item?.group;\n if(group && item.message.date !== message.date) {\n this.bubbleGroups.removeItem(item);\n modifiedGroups.add(group);\n }\n });\n }\n\n items.forEach(({bubble, message}) => {\n this.bubbleGroups.prepareForGrouping(bubble, message);\n });\n\n const groups = this.bubbleGroups.groupUngrouped();\n\n const avatarPromises = Array.from(groups).map((group) => {\n if(group.avatar) return;\n const firstItem = group.firstItem;\n if(firstItem && this.chat.isAvatarNeeded(firstItem.message)) {\n return group.createAvatar(firstItem.message);\n }\n }).filter(Boolean);\n\n if(modifiedGroups) {\n for(const group of modifiedGroups) {\n groups.add(group);\n }\n }\n\n return {\n groups: [...groups],\n avatarPromises\n };\n }\n\n public getMiddleware(additionalCallback?: () => boolean) {\n return this.middlewareHelper.get(additionalCallback);\n }\n\n private async wrapMediaSpoiler({\n media,\n promise,\n middleware,\n attachmentDiv\n }: {\n media: Photo.photo | MyDocument,\n promise: Promise<any>,\n middleware: Middleware,\n attachmentDiv: HTMLElement\n }) {\n await promise;\n if(!middleware()) {\n return;\n }\n\n const {width, height} = attachmentDiv.style;\n const container = await wrapMediaSpoiler({\n media,\n width: parseInt(width),\n height: parseInt(height),\n middleware,\n animationGroup: this.chat.animationGroup\n });\n\n if(!middleware()) {\n return;\n }\n\n attachmentDiv.append(container);\n }\n\n private async safeRenderMessage(\n message: Message.message | Message.messageService,\n reverse?: boolean,\n bubble?: HTMLElement,\n updatePosition = true,\n processResult?: (result: ReturnType<ChatBubbles['renderMessage']>, bubble: HTMLElement) => typeof result\n ) {\n if(!message || this.renderingMessages.has(message.mid) || (this.bubbles[message.mid] && !bubble)) {\n return;\n }\n\n const middlewareHelper = this.getMiddleware().create();\n const middleware = middlewareHelper.get();\n\n let result: Awaited<ReturnType<ChatBubbles['renderMessage']>> & {updatePosition: typeof updatePosition};\n try {\n this.renderingMessages.add(message.mid);\n\n // const groupedId = (message as Message.message).grouped_id;\n const newBubble = document.createElement('div');\n newBubble.middlewareHelper = middlewareHelper;\n newBubble.dataset.mid = '' + message.mid;\n newBubble.dataset.peerId = '' + message.peerId;\n newBubble.dataset.timestamp = '' + message.date;\n\n // const bubbleNew: Bubble = this.bubblesNew[message.mid] ??= {\n // bubble: newBubble,\n // mids: new Set(),\n // groupedId\n // };\n\n // bubbleNew.mids.add(message.mid);\n\n if(bubble) {\n bubble.middlewareHelper.destroy();\n this.skippedMids.delete(message.mid);\n\n this.bubblesToEject.add(bubble);\n this.bubblesToReplace.delete(bubble);\n this.bubblesToReplace.set(newBubble, bubble);\n this.bubbleGroups.changeBubbleByBubble(bubble, newBubble);\n }\n\n bubble = this.bubbles[message.mid] = newBubble;\n let originalPromise = this.renderMessage(message, reverse, bubble, middleware);\n if(processResult) {\n originalPromise = processResult(originalPromise, bubble);\n }\n\n const promise = originalPromise.then((r) => ((r && middleware() ? {...r, updatePosition} : undefined) as typeof result));\n\n this.renderMessagesQueue(promise.catch(() => undefined));\n\n result = await promise;\n if(!middleware()) {\n return;\n }\n\n if(!result) {\n this.skippedMids.add(+message.mid);\n }\n } catch(err) {\n this.log.error('renderMessage error:', err);\n }\n\n if(!middleware()) {\n return;\n }\n\n this.renderingMessages.delete(message.mid);\n return result;\n }\n\n // reverse means top\n private async renderMessage(\n message: Message.message | Message.messageService,\n reverse = false,\n bubble: HTMLElement,\n middleware: Middleware\n ) {\n // if(DEBUG) {\n // this.log('message to render:', message);\n // }\n\n // if(!bubble && this.bubbles[message.mid]) {\n // return;\n // }\n\n // await pause(1000);\n\n const isMessage = message._ === 'message';\n const groupedId = isMessage && message.grouped_id;\n let albumMids: number[], reactionsMessage: Message.message;\n const albumMessages = groupedId ? await this.managers.appMessagesManager.getMessagesByAlbum(groupedId) : undefined;\n\n const albumMustBeRenderedFull = this.chat.type !== 'pinned';\n\n if(groupedId && albumMustBeRenderedFull) { // will render only last album's message\n albumMids = albumMessages.map((message) => message.mid);\n const mainMid = getMainMidForGrouped(albumMids);\n if(message.mid !== mainMid) {\n return;\n }\n }\n\n if(isMessage) {\n reactionsMessage = groupedId ? albumMessages[0] : message;\n }\n\n // * can't use 'message.pFlags.out' here because this check will be used to define side of message (left-right)\n const our = this.chat.isOurMessage(message);\n\n const messageDiv = document.createElement('div');\n messageDiv.classList.add('message', 'spoilers-container');\n\n const contentWrapper = document.createElement('div');\n contentWrapper.classList.add('bubble-content-wrapper');\n\n const bubbleContainer = document.createElement('div');\n bubbleContainer.classList.add('bubble-content');\n\n bubble.classList.add('bubble');\n contentWrapper.append(bubbleContainer);\n bubble.append(contentWrapper);\n\n let isInUnread = !our &&\n !message.pFlags.out &&\n (\n message.pFlags.unread ||\n isMentionUnread(message)\n );\n\n if(!isInUnread && this.chat.peerId.isAnyChat()) {\n const readMaxId = await this.managers.appMessagesManager.getReadMaxIdIfUnread(this.chat.peerId, this.chat.threadId);\n if(readMaxId !== undefined && readMaxId < message.mid) {\n isInUnread = true;\n }\n }\n\n if(isInUnread && this.observer) {\n // this.log('not our message', message, message.pFlags.unread);\n this.observer.observe(bubble, this.unreadedObserverCallback);\n this.unreaded.set(bubble, message.mid);\n }\n\n const loadPromises: Promise<any>[] = [];\n const ret = {\n bubble,\n promises: loadPromises,\n message,\n reverse\n };\n\n const wrapOptions: WrapSomethingOptions = {\n lazyLoadQueue: this.lazyLoadQueue,\n middleware,\n customEmojiSize: this.chat.appImManager.customEmojiSize,\n animationGroup: this.chat.animationGroup\n };\n\n if(message._ === 'messageService' && (!message.action || !SERVICE_AS_REGULAR.has(message.action._))) {\n const action = message.action;\n if(action) {\n const _ = action._;\n\n const ignoreAction = IGNORE_ACTIONS.get(_);\n if(ignoreAction && (ignoreAction === true || ignoreAction(message))) {\n return;\n }\n\n if(langPack.hasOwnProperty(_) && !langPack[_]) {\n return;\n }\n }\n\n bubble.className = 'bubble service';\n\n bubbleContainer.replaceChildren();\n const s = document.createElement('div');\n s.classList.add('service-msg');\n if(action) {\n let promise: Promise<any>;\n if(action._ === 'messageActionChannelMigrateFrom') {\n const peerTitle = new PeerTitle();\n promise = peerTitle.update({peerId: action.chat_id.toPeerId(true), wrapOptions});\n s.append(i18n('ChatMigration.From', [peerTitle.element]));\n } else if(action._ === 'messageActionChatMigrateTo') {\n const peerTitle = new PeerTitle();\n promise = peerTitle.update({peerId: action.channel_id.toPeerId(true), wrapOptions});\n s.append(i18n('ChatMigration.To', [peerTitle.element]));\n } else {\n promise = wrapMessageActionTextNew({\n message,\n ...wrapOptions\n }).then((el) => s.append(el));\n }\n\n if(action._ === 'messageActionGiftPremium') {\n const content = bubbleContainer.cloneNode(false) as HTMLElement;\n content.classList.add('bubble-premium-gift-container');\n content.style.height = '12.875rem';\n content.style.width = '12.5rem';\n\n const service = s.cloneNode(false) as HTMLElement;\n service.classList.add('bubble-premium-gift-wrapper');\n\n const size = 160;\n\n const months = action.months;\n\n const durationAssetMap: {[key: number]: LottieAssetName} = {\n 3: 'Gift3',\n 6: 'Gift6',\n 12: 'Gift12'\n };\n\n const assetName = durationAssetMap[clamp(months, 3, 12)];\n\n const promise = wrapLocalSticker({\n width: size,\n height: size,\n assetName,\n middleware,\n loop: false,\n autoplay: liteMode.isAvailable('stickers_chat')\n }).then(({container, promise}) => {\n container.classList.add('bubble-premium-gift-sticker');\n container.style.position = 'relative';\n container.style.width = container.style.height = size + 'px';\n service.prepend(container);\n return promise;\n });\n\n const isYears = months >= 12 && !(months % 12);\n const duration = i18n(isYears ? 'Years' : 'Months', [isYears ? months / 12 : months]);\n\n const title = i18n('ActionGiftPremiumTitle');\n const subtitle = i18n('ActionGiftPremiumSubtitle', [duration]);\n title.classList.add('text-bold');\n\n service.append(title, subtitle);\n loadPromises.push(promise);\n\n content.append(service);\n bubbleContainer.after(content);\n }\n\n loadPromises.push(promise);\n }\n bubbleContainer.append(s);\n\n if(message.pFlags.is_single) { // * Ignore 'Discussion started'\n bubble.classList.add('is-group-last');\n }\n\n return ret;\n }\n\n let messageMedia: MessageMedia = isMessage && message.media;\n let needToSetHTML = true;\n let messageMessage: string, totalEntities: MessageEntity[], albumTextMessage: Message.message;\n if(isMessage) {\n if(groupedId && albumMustBeRenderedFull) {\n const t = albumTextMessage = getAlbumText(albumMessages);\n messageMessage = t?.message || '';\n // totalEntities = t.entities;\n totalEntities = t?.totalEntities || [];\n } else {\n messageMessage = message.message;\n // totalEntities = message.entities;\n totalEntities = message.totalEntities;\n }\n\n const document = (messageMedia as MessageMedia.messageMediaDocument)?.document as MyDocument;\n if(document) {\n if(document?.type === 'sticker') {\n messageMessage = totalEntities = undefined;\n } else if(!['video', 'gif'].includes(document.type)) {\n needToSetHTML = false;\n }\n }\n } else {\n if(message.action._ === 'messageActionPhoneCall') {\n messageMedia = {\n _: 'messageMediaCall',\n action: message.action\n };\n }\n }\n\n let bigEmojis = 0, customEmojiSize: MediaSize;\n if(totalEntities && !messageMedia) {\n const emojiEntities = totalEntities.filter((e) => e._ === 'messageEntityEmoji'/* || e._ === 'messageEntityCustomEmoji' */);\n const strLength = messageMessage.replace(/\\s/g, '').length;\n const emojiStrLength = emojiEntities.reduce((acc, curr) => acc + curr.length, 0);\n\n if(emojiStrLength === strLength /* && emojiEntities.length <= 3 *//* && totalEntities.length === emojiEntities.length */) {\n bigEmojis = Math.min(BIG_EMOJI_SIZES_LENGTH, emojiEntities.length);\n\n customEmojiSize = mediaSizes.active.customEmoji;\n\n const size = BIG_EMOJI_SIZES[bigEmojis];\n if(size) {\n customEmojiSize = makeMediaSize(size, size);\n bubble.style.setProperty('--emoji-size', size + 'px');\n }\n }\n }\n\n customEmojiSize ??= this.chat.appImManager.customEmojiSize;\n\n let maxMediaTimestamp = getMediaDurationFromMessage(albumTextMessage || message as Message.message);\n if(albumTextMessage && needToSetHTML) {\n bubble.dataset.textMid = '' + albumTextMessage.mid;\n }\n\n if(message.reply_to) {\n const replyToPeerId = message.reply_to.reply_to_peer_id ? getPeerId(message.reply_to.reply_to_peer_id) : this.peerId;\n bubble.dataset.replyToPeerId = '' + replyToPeerId;\n bubble.dataset.replyToMid = '' + message.reply_to_mid;\n\n if(maxMediaTimestamp === undefined) {\n const originalMessage = await rootScope.managers.appMessagesManager.getMessageByPeer(replyToPeerId, message.reply_to_mid);\n if(originalMessage) {\n maxMediaTimestamp = getMediaDurationFromMessage(originalMessage as Message.message);\n } else {\n // this.managers.appMessagesManager.fetchMessageReplyTo(message);\n // this.needUpdate.push({replyToPeerId, replyMid: message.reply_to_mid, mid: message.mid});\n maxMediaTimestamp = Infinity;\n }\n }\n }\n\n const richTextOptions: Parameters<typeof wrapRichText>[1] = {\n entities: totalEntities,\n passEntities: this.passEntities,\n loadPromises,\n lazyLoadQueue: this.lazyLoadQueue,\n customEmojiSize,\n middleware,\n animationGroup: this.chat.animationGroup,\n maxMediaTimestamp\n };\n\n const richText = messageMessage ? wrapRichText(messageMessage, richTextOptions) : undefined;\n\n let canHaveTail = true;\n let isStandaloneMedia = false;\n let attachmentDiv: HTMLElement;\n if(bigEmojis) {\n if(rootScope.settings.emoji.big) {\n const sticker = bigEmojis === 1 &&\n !totalEntities.find((entity) => entity._ === 'messageEntityCustomEmoji') &&\n await this.managers.appStickersManager.getAnimatedEmojiSticker(messageMessage);\n if(bigEmojis === 1 && !messageMedia && sticker) {\n messageMedia = {\n _: 'messageMediaDocument',\n document: sticker,\n pFlags: {}\n };\n } else {\n attachmentDiv = document.createElement('div');\n attachmentDiv.classList.add('attachment', 'spoilers-container');\n\n setInnerHTML(attachmentDiv, richText);\n\n bubbleContainer.append(attachmentDiv);\n }\n\n bubble.classList.add('is-message-empty', 'emoji-big');\n isStandaloneMedia = true;\n canHaveTail = false;\n needToSetHTML = false;\n }\n\n bubble.classList.add('can-have-big-emoji');\n }\n\n if(needToSetHTML) {\n setInnerHTML(messageDiv, richText);\n }\n\n const haveRTLChar = isRTL(messageMessage, true);\n\n const timeSpan = MessageRender.setTime({\n chatType: this.chat.type,\n message,\n reactionsMessage\n });\n messageDiv.append(timeSpan);\n bubbleContainer.prepend(messageDiv);\n // bubble.prepend(timeSpan, messageDiv); // that's bad\n\n if(haveRTLChar) {\n timeSpan.classList.add('is-block');\n }\n\n let topicNameButtonContainer: HTMLElement;\n if(isMessage && this.chat.isAllMessagesForum) {\n const result = await wrapTopicNameButton({\n peerId: this.peerId,\n threadId: getMessageThreadId(message, this.chat.isForum),\n lastMsgId: message.mid,\n wrapOptions: {\n middleware\n },\n withIcons: true\n });\n\n const {element} = result;\n // if(isStandaloneMedia) {\n // element.classList.add('floating-part');\n // }\n\n topicNameButtonContainer = document.createElement('div');\n topicNameButtonContainer.classList.add(/* 'name', */'topic-name-button-container');\n topicNameButtonContainer.append(element);\n }\n\n if(isMessage && message.views) {\n bubble.classList.add('channel-post');\n\n if(!message.fwd_from?.saved_from_msg_id && this.chat.type !== 'pinned') {\n const forward = document.createElement('div');\n forward.classList.add('bubble-beside-button', 'forward', 'tgico-forward_filled');\n bubbleContainer.prepend(forward);\n bubble.classList.add('with-beside-button');\n }\n\n if(!message.pFlags.is_outgoing && this.observer) {\n this.observer.observe(bubble, this.viewsObserverCallback);\n }\n }\n\n const replyMarkup = isMessage && message.reply_markup;\n let replyMarkupRows = replyMarkup?._ === 'replyInlineMarkup' && replyMarkup.rows;\n if(replyMarkupRows) {\n replyMarkupRows = replyMarkupRows.filter((row) => row.buttons.length);\n }\n\n if(replyMarkupRows) {\n const containerDiv = document.createElement('div');\n containerDiv.classList.add('reply-markup');\n replyMarkupRows.forEach((row) => {\n const buttons = row.buttons;\n\n const rowDiv = document.createElement('div');\n rowDiv.classList.add('reply-markup-row');\n\n buttons.forEach((button) => {\n let text: DocumentFragment | HTMLElement | string = wrapRichText(button.text, {noLinks: true, noLinebreaks: true});\n\n let buttonEl: HTMLButtonElement | HTMLAnchorElement;\n\n switch(button._) {\n case 'keyboardButtonUrl': {\n const r = wrapRichText(' ', {\n entities: [{\n _: 'messageEntityTextUrl',\n length: 1,\n offset: 0,\n url: button.url\n }]\n });\n\n buttonEl = htmlToDocumentFragment(r).firstElementChild as HTMLAnchorElement;\n buttonEl.classList.add('is-link');\n\n break;\n }\n\n case 'keyboardButtonSwitchInline': {\n buttonEl = document.createElement('button');\n buttonEl.classList.add('is-switch-inline');\n attachClickEvent(buttonEl, (e) => {\n cancelEvent(e);\n\n const botId = message.viaBotId || message.fromId;\n let promise: Promise<PeerId>;\n if(button.pFlags.same_peer) promise = Promise.resolve(this.peerId);\n else promise = this.managers.appInlineBotsManager.checkSwitchReturn(botId).then((peerId) => {\n if(peerId) {\n return peerId;\n }\n\n return new Promise<PeerId>((resolve, reject) => {\n const popup = PopupElement.createPopup(PopupForward, undefined, (peerId) => {\n resolve(peerId);\n });\n\n popup.addEventListener('close', () => {\n reject();\n });\n });\n });\n\n promise.then((peerId) => {\n const threadId = this.peerId === peerId ? this.chat.threadId : undefined;\n this.chat.appImManager.setInnerPeer({peerId});\n this.managers.appInlineBotsManager.switchInlineQuery(peerId, threadId, botId, button.query);\n });\n });\n break;\n }\n\n case 'keyboardButtonBuy': {\n const mediaInvoice = messageMedia._ === 'messageMediaInvoice' ? messageMedia : undefined;\n if(mediaInvoice?.extended_media) {\n break;\n }\n\n buttonEl = document.createElement('button');\n buttonEl.classList.add('is-buy');\n\n if(mediaInvoice?.receipt_msg_id) {\n text = i18n('Message.ReplyActionButtonShowReceipt');\n }\n\n break;\n }\n\n case 'keyboardButtonUrlAuth': {\n buttonEl = document.createElement('button');\n buttonEl.classList.add('is-url-auth');\n\n const {peerId} = this;\n const {mid} = message;\n const {url, button_id} = button;\n\n attachClickEvent(buttonEl, () => {\n const toggle = toggleDisability([buttonEl], true);\n this.chat.appImManager.handleUrlAuth({\n peerId,\n mid,\n url,\n buttonId: button_id\n }).then(() => {\n toggle();\n });\n });\n break;\n }\n\n default: {\n buttonEl = document.createElement('button');\n break;\n }\n }\n\n if(!buttonEl) {\n return;\n }\n\n buttonEl.classList.add('reply-markup-button', 'rp', 'tgico');\n const t = document.createElement('span');\n t.classList.add('reply-markup-button-text');\n if(typeof(text) === 'string') {\n t.insertAdjacentHTML('beforeend', text);\n } else {\n t.append(text);\n }\n\n ripple(buttonEl);\n buttonEl.append(t);\n\n rowDiv.append(buttonEl);\n });\n\n if(!rowDiv.childElementCount) {\n return;\n }\n\n containerDiv.append(rowDiv);\n });\n\n const haveButtons = !!containerDiv.childElementCount;\n\n haveButtons && attachClickEvent(containerDiv, (e) => {\n let target = e.target as HTMLElement;\n\n if(!target.classList.contains('reply-markup-button')) target = findUpClassName(target, 'reply-markup-button');\n if(\n !target ||\n target.classList.contains('is-link') ||\n target.classList.contains('is-switch-inline') ||\n target.classList.contains('is-buy') ||\n target.classList.contains('is-url-auth')\n ) return;\n\n cancelEvent(e);\n\n const column = whichChild(target);\n const row = replyMarkupRows[whichChild(target.parentElement)];\n\n if(!row.buttons || !row.buttons[column]) {\n this.log.warn('no such button', row, column, message);\n return;\n }\n\n const button = row.buttons[column];\n this.managers.appInlineBotsManager.callbackButtonClick(this.peerId, message.mid, button).then((callbackAnswer) => {\n if(typeof callbackAnswer.message === 'string' && callbackAnswer.message.length) {\n toast(wrapRichText(callbackAnswer.message, {noLinks: true, noLinebreaks: true}));\n }\n\n // console.log('callbackButtonClick callbackAnswer:', callbackAnswer);\n });\n });\n\n if(haveButtons) {\n // canHaveTail = false;\n bubble.classList.add('with-reply-markup');\n contentWrapper.append(containerDiv);\n }\n }\n\n const isOutgoing = message.pFlags.is_outgoing/* && this.peerId !== rootScope.myId */;\n if(our) {\n if(message.pFlags.unread || isOutgoing) this.unreadOut.add(message.mid);\n let status = '';\n if(message.error) status = 'is-error';\n else if(isOutgoing) status = 'is-sending';\n else status = message.pFlags.unread || (message as Message.message).pFlags.is_scheduled ? 'is-sent' : 'is-read';\n bubble.classList.add(status);\n }\n\n if(isOutgoing && !message.error) {\n bubble.classList.add('is-outgoing');\n }\n\n const messageWithReplies = isMessage && await this.managers.appMessagesManager.getMessageWithCommentReplies(message);\n const withReplies = !!messageWithReplies && message.mid > 0;\n\n if(withReplies) {\n bubble.classList.add('with-replies');\n }\n\n const fwdFrom = isMessage && message.fwd_from;\n const fwdFromId = isMessage && message.fwdFromId;\n\n const isOut = this.chat.isOutMessage(message);\n let nameContainer: HTMLElement = bubbleContainer;\n\n const canHideNameIfMedia = !message.viaBotId && (message.fromId === rootScope.myId || !message.pFlags.out);\n\n const isMessageEmpty = !messageMessage/* && (!topicNameButtonContainer || isStandaloneMedia) */;\n\n let viewButton: HTMLAnchorElement;\n // media\n if(messageMedia/* && messageMedia._ === 'messageMediaPhoto' */) {\n attachmentDiv = document.createElement('div');\n attachmentDiv.classList.add('attachment');\n\n if(isMessageEmpty) {\n bubble.classList.add('is-message-empty');\n }\n\n let processingWebPage = false;\n\n /* if(isMessage) */switch(messageMedia._) {\n case 'messageMediaPhoto': {\n const photo = messageMedia.photo;\n // //////this.log('messageMediaPhoto', photo);\n\n if(isMessageEmpty) {\n canHaveTail = false;\n }\n\n if(canHideNameIfMedia) {\n bubble.classList.add('hide-name');\n }\n\n bubble.classList.add('photo');\n\n if(albumMustBeRenderedFull && groupedId && albumMids.length !== 1) {\n bubble.classList.add('is-album', 'is-grouped');\n wrapAlbum({\n messages: albumMessages,\n attachmentDiv,\n middleware: this.getMiddleware(),\n isOut: our,\n lazyLoadQueue: this.lazyLoadQueue,\n chat: this.chat,\n loadPromises,\n autoDownload: this.chat.autoDownload\n });\n\n break;\n }\n\n const withTail = !IS_ANDROID && canHaveTail && !withReplies && USE_MEDIA_TAILS;\n if(withTail) bubble.classList.add('with-media-tail');\n const p = wrapPhoto({\n photo: photo as Photo.photo,\n message,\n container: attachmentDiv,\n withTail,\n isOut,\n lazyLoadQueue: this.lazyLoadQueue,\n middleware: this.getMiddleware(),\n loadPromises,\n autoDownloadSize: this.chat.autoDownload.photo\n });\n\n if(messageMedia.pFlags.spoiler) {\n loadPromises.push(this.wrapMediaSpoiler({\n media: photo as Photo.photo,\n promise: p,\n middleware,\n attachmentDiv\n }));\n }\n\n break;\n }\n\n case 'messageMediaWebPage': {\n processingWebPage = true;\n\n const webPage: WebPage = messageMedia.webpage;\n // //////this.log('messageMediaWebPage', webpage);\n if(webPage._ !== 'webPage') {\n break;\n }\n\n const wrapped = wrapUrl(webPage.url);\n if(wrapped?.onclick === 'im') {\n const map: {[type: string]: LangPackKey} = {\n telegram_channel: 'Chat.Message.ViewChannel',\n telegram_megagroup: 'OpenGroup',\n telegram_bot: 'Chat.Message.ViewBot'\n };\n\n const langPackKey = map[webPage.type] || 'OpenMessage';\n viewButton = this.makeViewButton({text: langPackKey, asLink: true});\n viewButton.href = wrapped.url;\n viewButton.setAttribute('onclick', `${wrapped.onclick}(this)`);\n }\n\n bubble.classList.add('webpage');\n\n const box = document.createElement('div');\n box.classList.add('web');\n\n const quote = document.createElement('div');\n quote.classList.add('quote');\n\n let previewResizer: HTMLDivElement, preview: HTMLDivElement;\n const photo: Photo.photo = webPage.photo as any;\n if(photo || webPage.document) {\n previewResizer = document.createElement('div');\n previewResizer.classList.add('preview-resizer');\n preview = document.createElement('div');\n preview.classList.add('preview');\n previewResizer.append(preview);\n }\n\n const quoteTextDiv = document.createElement('div');\n quoteTextDiv.classList.add('quote-text');\n\n const doc = webPage.document as MyDocument;\n if(doc) {\n if(doc.type === 'gif' || doc.type === 'video' || doc.type === 'round') {\n // if(doc.size <= 20e6) {\n const mediaSize = doc.type === 'round' ? mediaSizes.active.round : mediaSizes.active.webpage;\n if(doc.type === 'round') {\n bubble.classList.add('round');\n preview.classList.add('is-round');\n } else {\n bubble.classList.add('video');\n }\n wrapVideo({\n doc,\n container: preview,\n message: message as Message.message,\n boxWidth: mediaSize.width,\n boxHeight: mediaSize.height,\n lazyLoadQueue: this.lazyLoadQueue,\n middleware: this.getMiddleware(),\n isOut,\n group: this.chat.animationGroup,\n loadPromises,\n autoDownload: this.chat.autoDownload,\n noInfo: message.mid < 0\n });\n // }\n } else {\n const docDiv = await wrapDocument({\n message: message as Message.message,\n autoDownloadSize: this.chat.autoDownload.file,\n lazyLoadQueue: this.lazyLoadQueue,\n loadPromises,\n sizeType: 'documentName',\n searchContext: {\n useSearch: false,\n peerId: this.peerId,\n inputFilter: {\n _: 'inputMessagesFilterEmpty'\n }\n },\n fontSize: rootScope.settings.messagesTextSize,\n canTranscribeVoice: true\n });\n preview.append(docDiv);\n preview.classList.add('preview-with-document');\n quoteTextDiv.classList.add('has-document');\n // messageDiv.classList.add((webpage.type || 'document') + '-message');\n // doc = null;\n }\n }\n\n if(previewResizer) {\n quoteTextDiv.append(previewResizer);\n }\n\n let t: HTMLElement;\n if(webPage.site_name) {\n const html = wrapRichText(webPage.url);\n const a: HTMLAnchorElement = htmlToDocumentFragment(html).firstElementChild as any;\n a.classList.add('webpage-name');\n const strong = document.createElement('strong');\n setInnerHTML(strong, wrapEmojiText(webPage.site_name));\n a.textContent = '';\n a.append(strong);\n quoteTextDiv.append(a);\n t = a;\n }\n\n const title = wrapWebPageTitle(webPage);\n if(title.textContent) {\n const titleDiv = document.createElement('div');\n titleDiv.classList.add('title');\n const strong = document.createElement('strong');\n setInnerHTML(strong, title);\n titleDiv.append(strong);\n quoteTextDiv.append(titleDiv);\n t = titleDiv;\n }\n\n const description = wrapWebPageDescription(webPage);\n if(description.textContent) {\n const textDiv = document.createElement('div');\n textDiv.classList.add('text');\n setInnerHTML(textDiv, description);\n quoteTextDiv.append(textDiv);\n t = textDiv;\n }\n\n /* if(t) {\n t.append(timeSpan);\n } else {\n box.classList.add('no-text');\n } */\n\n quote.append(quoteTextDiv);\n\n if(photo && !doc) {\n bubble.classList.add('photo');\n\n const size: PhotoSize.photoSize = photo.sizes[photo.sizes.length - 1] as any;\n let isSquare = false;\n if(size.w === size.h && t) {\n bubble.classList.add('is-square-photo');\n isSquare = true;\n setAttachmentSize(photo, preview, 48, 48, false);\n\n /* if(t) {\n t.append(timeSpan);\n } */\n } else if(size.h > size.w) {\n bubble.classList.add('is-vertical-photo');\n }\n\n wrapPhoto({\n photo,\n message,\n container: preview,\n boxWidth: isSquare ? 0 : mediaSizes.active.webpage.width,\n boxHeight: isSquare ? 0 : mediaSizes.active.webpage.height,\n isOut,\n lazyLoadQueue: this.lazyLoadQueue,\n middleware: this.getMiddleware(),\n loadPromises,\n withoutPreloader: isSquare,\n autoDownloadSize: this.chat.autoDownload.photo\n });\n }\n\n box.append(quote);\n\n // bubble.prepend(box);\n // if(timeSpan.parentElement === messageDiv) {\n messageDiv.insertBefore(box, timeSpan);\n // } else {\n // messageDiv.append(box);\n // }\n\n // this.log('night running', bubble.scrollHeight);\n\n break;\n }\n\n case 'messageMediaDocument': {\n const doc = messageMedia.document as MyDocument;\n\n // this.log('messageMediaDocument', doc, bubble);\n\n if(doc.sticker/* && doc.size <= 1e6 */) {\n bubble.classList.add('sticker');\n canHaveTail = false;\n isStandaloneMedia = true;\n\n if(doc.animated) {\n bubble.classList.add('sticker-animated');\n }\n\n const sizes = mediaSizes.active;\n const isEmoji = bubble.classList.contains('emoji-big');\n const boxSize = isEmoji ? sizes.emojiSticker : (doc.animated ? sizes.animatedSticker : sizes.staticSticker);\n setAttachmentSize(doc, attachmentDiv, boxSize.width, boxSize.height);\n // let preloader = new ProgressivePreloader(attachmentDiv, false);\n bubbleContainer.style.minWidth = attachmentDiv.style.width;\n bubbleContainer.style.minHeight = attachmentDiv.style.height;\n // appPhotosManager.setAttachmentSize(doc, bubble);\n wrapSticker({\n doc,\n div: attachmentDiv,\n middleware,\n lazyLoadQueue: this.lazyLoadQueue,\n group: this.chat.animationGroup,\n // play: !!message.pending || !multipleRender,\n play: true,\n liteModeKey: 'stickers_chat',\n loop: true,\n emoji: isEmoji ? messageMessage : undefined,\n withThumb: true,\n loadPromises,\n isOut,\n noPremium: messageMedia?.pFlags?.nopremium\n });\n\n if((getStickerEffectThumb(doc) || isEmoji) && (isInUnread || isOutgoing)/* || true */) {\n this.observer.observe(bubble, this.stickerEffectObserverCallback);\n }\n } else if(doc.type === 'video' || doc.type === 'gif' || doc.type === 'round'/* && doc.size <= 20e6 */) {\n // this.log('never get free 2', doc);\n\n const isRound = doc.type === 'round';\n if(isRound) {\n isStandaloneMedia = true;\n }\n\n if(isRound || isMessageEmpty) {\n canHaveTail = false;\n }\n\n if(canHideNameIfMedia) {\n bubble.classList.add('hide-name');\n }\n\n bubble.classList.add(isRound ? 'round' : 'video');\n if(albumMustBeRenderedFull && groupedId && albumMids.length !== 1) {\n bubble.classList.add('is-album', 'is-grouped');\n\n wrapAlbum({\n messages: albumMessages,\n attachmentDiv,\n middleware,\n isOut: our,\n lazyLoadQueue: this.lazyLoadQueue,\n chat: this.chat,\n loadPromises,\n autoDownload: this.chat.autoDownload\n });\n } else {\n const withTail = !IS_ANDROID && !IS_APPLE && !isRound && canHaveTail && !withReplies && USE_MEDIA_TAILS;\n if(withTail) bubble.classList.add('with-media-tail');\n const p = wrapVideo({\n doc,\n container: attachmentDiv,\n message: message as Message.message,\n boxWidth: mediaSizes.active.regular.width,\n boxHeight: mediaSizes.active.regular.height,\n withTail,\n isOut,\n lazyLoadQueue: this.lazyLoadQueue,\n middleware,\n group: this.chat.animationGroup,\n loadPromises,\n autoDownload: this.chat.autoDownload,\n searchContext: isRound ? {\n peerId: this.peerId,\n inputFilter: {_: 'inputMessagesFilterRoundVoice'},\n threadId: this.chat.threadId,\n useSearch: !(message as Message.message).pFlags.is_scheduled,\n isScheduled: (message as Message.message).pFlags.is_scheduled\n } : undefined,\n noInfo: message.mid < 0,\n noAutoplayAttribute: !!messageMedia.pFlags.spoiler\n });\n\n if(messageMedia.pFlags.spoiler) {\n loadPromises.push(this.wrapMediaSpoiler({\n media: doc,\n promise: p,\n middleware,\n attachmentDiv\n }));\n }\n }\n } else {\n const newNameContainer = await wrapGroupedDocuments({\n albumMustBeRenderedFull,\n message,\n bubble,\n messageDiv,\n chat: this.chat,\n loadPromises,\n autoDownloadSize: this.chat.autoDownload.file,\n lazyLoadQueue: this.lazyLoadQueue,\n searchContext: doc.type === 'voice' || doc.type === 'audio' ? {\n peerId: this.peerId,\n inputFilter: {_: doc.type === 'voice' ? 'inputMessagesFilterRoundVoice' : 'inputMessagesFilterMusic'},\n threadId: this.chat.threadId,\n useSearch: !(message as Message.message).pFlags.is_scheduled,\n isScheduled: (message as Message.message).pFlags.is_scheduled\n } : undefined,\n sizeType: 'documentName',\n fontSize: rootScope.settings.messagesTextSize,\n richTextFragment: typeof(richText) === 'string' ? undefined : richText,\n richTextOptions,\n canTranscribeVoice: true\n });\n\n if(newNameContainer) {\n nameContainer = newNameContainer;\n }\n\n const lastContainer = messageDiv.lastElementChild.querySelector('.document-message, .document, .audio');\n // lastContainer && lastContainer.append(timeSpan.cloneNode(true));\n lastContainer && lastContainer.append(timeSpan);\n\n bubble.classList.remove('is-message-empty');\n const addClassName = (!(['photo', 'pdf'] as MyDocument['type'][]).includes(doc.type) ? doc.type || 'document' : 'document') + '-message';\n messageDiv.classList.add(addClassName);\n\n if(doc.type === 'audio' || doc.type === 'voice') {\n bubble.classList.add('min-content');\n }\n\n processingWebPage = true;\n }\n\n break;\n }\n\n case 'messageMediaCall': {\n const action = messageMedia.action;\n const div = document.createElement('div');\n div.classList.add('bubble-call', action.pFlags.video ? 'tgico-videocamera' : 'tgico-phone');\n\n const type: CallType = action.pFlags.video ? 'video' : 'voice';\n div.dataset.type = type;\n\n const title = document.createElement('div');\n title.classList.add('bubble-call-title');\n\n _i18n(title, isOut ?\n (action.pFlags.video ? 'CallMessageVideoOutgoing' : 'CallMessageOutgoing') :\n (action.pFlags.video ? 'CallMessageVideoIncoming' : 'CallMessageIncoming'));\n\n const subtitle = document.createElement('div');\n subtitle.classList.add('bubble-call-subtitle');\n\n if(action.duration !== undefined) {\n subtitle.append(formatCallDuration(action.duration));\n } else {\n let langPackKey: LangPackKey;\n switch(action.reason._) {\n case 'phoneCallDiscardReasonBusy':\n langPackKey = 'Call.StatusBusy';\n break;\n case 'phoneCallDiscardReasonMissed':\n langPackKey = 'Chat.Service.Call.Missed';\n break;\n // case 'phoneCallDiscardReasonHangup':\n default:\n langPackKey = 'Chat.Service.Call.Cancelled';\n break;\n }\n\n subtitle.classList.add('is-reason');\n _i18n(subtitle, langPackKey);\n }\n\n subtitle.classList.add('tgico', 'arrow-' + (action.duration !== undefined ? 'green' : 'red'));\n\n div.append(title, subtitle);\n\n processingWebPage = true;\n\n bubble.classList.remove('is-message-empty');\n messageDiv.classList.add('call-message');\n messageDiv.append(div);\n\n break;\n }\n\n case 'messageMediaContact': {\n // this.log('wrapping contact', message);\n\n const contact = messageMedia;\n const contactDiv = document.createElement('div');\n contactDiv.classList.add('contact');\n contactDiv.dataset.peerId = '' + contact.user_id;\n\n processingWebPage = true;\n\n const contactDetails = document.createElement('div');\n contactDetails.className = 'contact-details';\n const contactNameDiv = document.createElement('div');\n contactNameDiv.className = 'contact-name';\n const fullName = [\n contact.first_name,\n contact.last_name\n ].filter(Boolean).join(' ');\n contactNameDiv.append(\n fullName.trim() ? wrapEmojiText(fullName) : i18n('AttachContact')\n );\n\n const contactNumberDiv = document.createElement('div');\n contactNumberDiv.className = 'contact-number';\n contactNumberDiv.textContent = contact.phone_number ? '+' + formatPhoneNumber(contact.phone_number).formatted : 'Unknown phone number';\n\n contactDiv.append(contactDetails);\n contactDetails.append(contactNameDiv, contactNumberDiv);\n\n const avatarElem = new AvatarElement();\n avatarElem.updateWithOptions({\n lazyLoadQueue: this.lazyLoadQueue,\n peerId: contact.user_id.toPeerId(),\n peerTitle: contact.user_id ? undefined : (fullName.trim() ? fullName : I18n.format('AttachContact', true)[0])\n });\n avatarElem.classList.add('contact-avatar', 'avatar-54');\n\n contactDiv.prepend(avatarElem);\n\n bubble.classList.remove('is-message-empty');\n messageDiv.classList.add('contact-message');\n messageDiv.append(contactDiv);\n\n break;\n }\n\n case 'messageMediaPoll': {\n bubble.classList.remove('is-message-empty');\n\n const pollElement = wrapPoll(message);\n messageDiv.prepend(pollElement);\n messageDiv.classList.add('poll-message');\n\n break;\n }\n\n case 'messageMediaInvoice': {\n const isTest = messageMedia.pFlags.test;\n const extendedMedia = messageMedia.extended_media;\n const isAlreadyPaid = extendedMedia?._ === 'messageExtendedMedia';\n const isNotPaid = extendedMedia?._ === 'messageExtendedMediaPreview';\n let innerMedia = isAlreadyPaid ?\n (extendedMedia.media as MessageMedia.messageMediaPhoto).photo as Photo.photo ||\n (extendedMedia.media as MessageMedia.messageMediaDocument).document as Document.document :\n messageMedia.photo;\n\n const wrappedPrice = paymentsWrapCurrencyAmount(messageMedia.total_amount, messageMedia.currency);\n let priceEl: HTMLElement;\n if(!extendedMedia) {\n priceEl = document.createElement(innerMedia ? 'span' : 'div');\n const f = document.createDocumentFragment();\n const l = i18n(messageMedia.receipt_msg_id ? 'PaymentReceipt' : (isTest ? 'PaymentTestInvoice' : 'PaymentInvoice'));\n l.classList.add('text-uppercase');\n const joiner = ' ' + NBSP;\n const p = document.createElement('span');\n p.classList.add('text-bold');\n p.textContent = wrappedPrice + joiner;\n f.append(p, l);\n if(isTest && messageMedia.receipt_msg_id) {\n const a = document.createElement('span');\n a.classList.add('text-uppercase', 'pre-wrap');\n a.append(joiner + '(Test)');\n f.append(a);\n }\n setInnerHTML(priceEl, f);\n } else if(isNotPaid) {\n priceEl = document.createElement('span');\n priceEl.classList.add('extended-media-buy', 'tgico-premium_lock');\n attachmentDiv.classList.add('is-buy');\n _i18n(priceEl, 'Checkout.PayPrice', [wrappedPrice]);\n\n if(extendedMedia.video_duration !== undefined) {\n const videoTime = document.createElement('span');\n videoTime.classList.add('video-time');\n videoTime.textContent = toHHMMSS(extendedMedia.video_duration, false);\n attachmentDiv.append(videoTime);\n }\n }\n\n if(isNotPaid) {\n (extendedMedia.thumb as PhotoSize.photoStrippedSize).w = extendedMedia.w;\n (extendedMedia.thumb as PhotoSize.photoStrippedSize).h = extendedMedia.h;\n innerMedia = {\n _: 'photo',\n access_hash: '',\n pFlags: {},\n date: 0,\n dc_id: 0,\n file_reference: [],\n id: 0,\n sizes: [extendedMedia.thumb]\n };\n }\n\n if(innerMedia) {\n const mediaSize = extendedMedia ? mediaSizes.active.extendedInvoice : mediaSizes.active.invoice;\n if(innerMedia._ === 'document') {\n wrapVideo({\n doc: innerMedia,\n container: attachmentDiv,\n withTail: false,\n isOut,\n lazyLoadQueue: this.lazyLoadQueue,\n middleware,\n loadPromises,\n boxWidth: mediaSize.width,\n boxHeight: mediaSize.height,\n group: this.chat.animationGroup,\n message: message as Message.message\n });\n bubble.classList.add('video');\n } else {\n wrapPhoto({\n photo: innerMedia,\n container: attachmentDiv,\n withTail: false,\n isOut,\n lazyLoadQueue: this.lazyLoadQueue,\n middleware,\n loadPromises,\n boxWidth: mediaSize.width,\n boxHeight: mediaSize.height,\n message: isAlreadyPaid ? message : undefined\n });\n bubble.classList.add('photo');\n }\n\n if(priceEl) {\n if(!extendedMedia) {\n priceEl.classList.add('video-time');\n }\n\n attachmentDiv.append(priceEl);\n }\n } else {\n attachmentDiv = undefined;\n }\n\n if(isNotPaid) {\n const {mid} = message;\n this.extendedMediaMessages.add(mid);\n middleware.onClean(() => {\n this.extendedMediaMessages.delete(mid);\n });\n this.setExtendedMediaMessagesPollInterval();\n\n const {width, height} = attachmentDiv.style;\n const dotRenderer = DotRenderer.create({\n width: parseInt(width),\n height: parseInt(height),\n middleware,\n animationGroup: this.chat.animationGroup\n });\n attachmentDiv.append(dotRenderer.canvas);\n }\n\n let titleDiv: HTMLElement;\n if(!extendedMedia) {\n titleDiv = document.createElement('div');\n titleDiv.classList.add('bubble-primary-color');\n setInnerHTML(titleDiv, wrapEmojiText(messageMedia.title));\n }\n\n const richText = isAlreadyPaid ? undefined : wrapEmojiText(messageMedia.description);\n messageDiv.prepend(...[titleDiv, !innerMedia && priceEl, richText].filter(Boolean));\n\n if(!richText) canHaveTail = false;\n else bubble.classList.remove('is-message-empty');\n bubble.classList.add('is-invoice');\n\n break;\n }\n\n default:\n attachmentDiv = undefined;\n bubble.classList.remove('is-message-empty');\n messageDiv.append(i18n(UNSUPPORTED_LANG_PACK_KEY), timeSpan);\n this.log.warn('unrecognized media type:', messageMedia._, message);\n break;\n }\n\n if(!processingWebPage && attachmentDiv) {\n bubbleContainer.append(attachmentDiv);\n }\n\n /* if(bubble.classList.contains('is-message-empty') && (bubble.classList.contains('photo') || bubble.classList.contains('video'))) {\n bubble.classList.add('no-tail');\n\n if(!bubble.classList.contains('with-media-tail')) {\n bubble.classList.add('use-border-radius');\n }\n } */\n }\n\n if(isStandaloneMedia) {\n bubble.classList.add('just-media');\n }\n\n if(viewButton) {\n timeSpan.before(viewButton);\n // messageDiv.append(viewButton);\n }\n\n let savedFrom = '';\n\n // const needName = ((peerId.isAnyChat() && (peerId !== message.fromId || our)) && message.fromId !== rootScope.myId) || message.viaBotId;\n const needName = (message.fromId !== rootScope.myId && this.chat.isAnyGroup) || message.viaBotId || (message as Message.message).pFlags.sponsored;\n if(needName || fwdFrom || message.reply_to_mid || topicNameButtonContainer) { // chat\n let title: HTMLElement | DocumentFragment;\n let titleVia: typeof title;\n\n const isForwardFromChannel = message.from_id?._ === 'peerChannel' && message.fromId === fwdFromId;\n\n const mustHaveName = !!(message.viaBotId/* || topicNameButtonContainer */);\n const isHidden = fwdFrom && !fwdFrom.from_id;\n if(message.viaBotId) {\n titleVia = document.createElement('span');\n titleVia.innerText = '@' + (await this.managers.appPeersManager.getPeerUsername(message.viaBotId));\n titleVia.classList.add('peer-title');\n }\n\n if(mustHaveName) {\n bubble.classList.add('must-have-name');\n }\n\n const isForward = fwdFromId || fwdFrom;\n if(isHidden) {\n title = document.createElement('span');\n setInnerHTML(title, wrapEmojiText(fwdFrom.from_name));\n title.classList.add('peer-title');\n bubble.classList.add('hidden-profile');\n } else {\n title = new PeerTitle({\n peerId: fwdFromId || message.fromId,\n withPremiumIcon: !isForward,\n wrapOptions\n }).element;\n }\n\n let replyContainer: HTMLElement;\n if(\n isMessage &&\n message.reply_to_mid &&\n message.reply_to_mid !== this.chat.threadId &&\n (!this.chat.isAllMessagesForum || message.reply_to.reply_to_top_id)\n ) {\n replyContainer = await MessageRender.setReply({\n chat: this.chat,\n bubble,\n bubbleContainer,\n message\n });\n }\n\n // this.log(title);\n\n let nameDiv: HTMLElement;\n if(isForward) {\n if(this.peerId !== rootScope.myId && !isForwardFromChannel) {\n bubble.classList.add('forwarded');\n }\n\n if(message.savedFrom) {\n savedFrom = message.savedFrom;\n title.dataset.savedFrom = savedFrom;\n }\n\n nameDiv = document.createElement('div');\n title.dataset.peerId = '' + fwdFromId;\n\n if((this.peerId === rootScope.myId || this.peerId === REPLIES_PEER_ID || isForwardFromChannel) && !isStandaloneMedia) {\n nameDiv.style.color = getPeerColorById(fwdFromId, false);\n nameDiv.classList.add('colored-name');\n nameDiv.append(title);\n } else {\n /* const fromTitle = message.fromId === this.myID || appPeersManager.isBroadcast(fwdFromId || message.fromId) ? '' : `<div class=\"name\" data-peer-id=\"${message.fromId}\" style=\"color: ${appPeersManager.getPeerColorByID(message.fromId, false)};\">${appPeersManager.getPeerTitle(message.fromId)}</div>`;\n nameDiv.innerHTML = fromTitle + 'Forwarded from ' + title; */\n const args: FormatterArguments = [title];\n if(isStandaloneMedia) {\n const br = document.createElement('br');\n br.classList.add('hide-ol');\n args.unshift(br);\n }\n nameDiv.append(i18n('ForwardedFrom', [args]));\n }\n } else if(!message.viaBotId) {\n if(!isStandaloneMedia && needName) {\n nameDiv = document.createElement('div');\n nameDiv.append(title);\n\n const peer = await this.managers.appPeersManager.getPeer(message.fromId);\n const pFlags = (peer as User.user)?.pFlags;\n if(pFlags && (pFlags.scam || pFlags.fake)) {\n nameDiv.append(generateFakeIcon(pFlags.scam));\n }\n\n if(!our) {\n nameDiv.style.color = getPeerColorById(message.fromId, false);\n nameDiv.classList.add('colored-name');\n }\n\n nameDiv.dataset.peerId = '' + message.fromId;\n } else /* if(!message.reply_to_mid) */ {\n bubble.classList.add('hide-name');\n }\n }\n\n if(message.viaBotId) {\n if(!nameDiv) {\n nameDiv = document.createElement('div');\n } else {\n nameDiv.append(' ');\n }\n\n const span = document.createElement('span');\n span.append(i18n('ViaBot'), ' ', titleVia);\n span.classList.add('is-via');\n\n nameDiv.append(span);\n }\n\n if(topicNameButtonContainer) {\n if(isStandaloneMedia) {\n topicNameButtonContainer.classList.add('floating-part');\n } else {\n if(!nameDiv) {\n nameDiv = document.createElement('div');\n }\n\n nameDiv.append(topicNameButtonContainer);\n\n bubble.classList.remove('hide-name');\n }\n }\n\n if(nameDiv) {\n nameDiv.classList.add('name');\n\n if(isStandaloneMedia) {\n nameContainer.append(nameContainer = document.createElement('div'));\n nameContainer.classList.add('name-with-reply', 'floating-part');\n } else {\n nameDiv.classList.add('floating-part');\n }\n\n nameContainer.append(nameDiv);\n\n if(isStandaloneMedia && replyContainer) {\n nameContainer.append(replyContainer);\n }\n } else if(isStandaloneMedia && replyContainer) {\n replyContainer.classList.add('floating-part');\n }\n\n if(title && !isHidden && !fwdFromId && this.canShowRanks) {\n const processRank = () => {\n const rank = this.ranks.get(message.fromId);\n if(!rank) {\n return;\n }\n\n (title as HTMLElement).after(this.createBubbleNameRank(rank));\n };\n\n if(this.ranks) {\n processRank();\n } else {\n const processRanks = this.processRanks;\n processRanks.add(processRank);\n\n middleware.onDestroy(() => {\n processRanks.delete(processRank);\n });\n }\n } else if(isForwardFromChannel) {\n (title as HTMLElement).after(this.createBubbleNameRank(0));\n }\n\n if(topicNameButtonContainer && isStandaloneMedia) {\n if(!attachmentDiv) {\n this.log.error('no attachment div?', bubble, message);\n debugger;\n } else {\n attachmentDiv.after(topicNameButtonContainer);\n }\n }\n } else {\n bubble.classList.add('hide-name');\n }\n\n if(this.chat.type === 'pinned') {\n savedFrom = `${this.chat.peerId}_${message.mid}`;\n }\n\n const isThreadStarter = messageWithReplies && messageWithReplies.mid === this.chat.threadId;\n if(isThreadStarter) {\n bubble.classList.add('is-thread-starter', 'is-group-last');\n }\n\n if(savedFrom && (this.chat.type === 'pinned' || fwdFrom.saved_from_msg_id) && this.peerId !== REPLIES_PEER_ID) {\n const goto = document.createElement('div');\n goto.classList.add('bubble-beside-button', 'goto-original', 'tgico-arrow_next');\n bubbleContainer.append(goto);\n bubble.dataset.savedFrom = savedFrom;\n bubble.classList.add('with-beside-button');\n }\n\n bubble.classList.add(isOut ? 'is-out' : 'is-in');\n\n if(withReplies) {\n const isFooter = MessageRender.renderReplies({\n bubble,\n bubbleContainer,\n message: messageWithReplies,\n messageDiv,\n loadPromises,\n lazyLoadQueue: this.lazyLoadQueue\n });\n\n if(isFooter) {\n canHaveTail = true;\n } else {\n bubble.classList.add('with-beside-replies');\n }\n }\n\n if(isMessage) {\n this.appendReactionsElementToBubble(bubble, message, reactionsMessage);\n }\n\n /* if(isMessage) {\n const reactionHover = document.createElement('div');\n reactionHover.classList.add('bubble-reaction-hover');\n contentWrapper.append(reactionHover);\n } */\n\n if(canHaveTail) {\n bubble.classList.add('can-have-tail');\n\n bubbleContainer.append(generateTail());\n }\n\n return ret;\n }\n\n private appendReactionsElementToBubble(\n bubble: HTMLElement,\n message: Message.message,\n reactionsMessage: Message.message,\n changedResults?: ReactionCount[]\n ) {\n if(this.peerId.isUser() && USER_REACTIONS_INLINE/* || true */) {\n return;\n }\n\n if(!reactionsMessage?.reactions || !reactionsMessage.reactions.results.length) {\n return;\n }\n\n // message = this.appMessagesManager.getMessageWithReactions(message);\n\n const reactionsElement = new ReactionsElement();\n reactionsElement.init(reactionsMessage, 'block', bubble.middlewareHelper.get());\n reactionsElement.render(changedResults);\n\n if(bubble.classList.contains('is-message-empty')) {\n bubble.querySelector('.bubble-content-wrapper').append(reactionsElement);\n } else {\n const messageDiv = bubble.querySelector('.message');\n if(bubble.classList.contains('is-multiple-documents')) {\n const documentContainer = messageDiv.lastElementChild as HTMLElement;\n let documentMessageDiv = documentContainer.querySelector('.document-message');\n\n let timeSpan: HTMLElement = documentMessageDiv && documentMessageDiv.querySelector('.time');\n if(!timeSpan) {\n timeSpan = MessageRender.setTime({\n chatType: this.chat.type,\n message,\n reactionsMessage\n });\n }\n\n reactionsElement.append(timeSpan);\n\n if(!documentMessageDiv) {\n documentMessageDiv = document.createElement('div');\n documentMessageDiv.classList.add('document-message');\n documentContainer.querySelector('.document-wrapper').prepend(documentMessageDiv);\n }\n\n documentMessageDiv.append(reactionsElement);\n } else {\n const timeSpan = Array.from(bubble.querySelectorAll('.time')).pop();\n reactionsElement.append(timeSpan);\n\n messageDiv.append(reactionsElement);\n }\n }\n }\n\n private createBubbleNameRank(rank: ReturnType<typeof getParticipantRank> | 0) {\n const span = document.createElement('span');\n span.classList.add('bubble-name-rank');\n span.append(wrapParticipantRank(rank));\n return span;\n }\n\n private prepareToSaveScroll(reverse?: boolean) {\n const isMounted = !!this.chatInner.parentElement;\n if(!isMounted) {\n return {};\n }\n\n const log = this.log.bindPrefix('prepareToSaveScroll');\n log('save');\n const scrollSaver = this.createScrollSaver(reverse);\n scrollSaver.save(); // * let's save scroll position by point before the slicing, not after\n\n if(this.getRenderedLength() && !this.chat.setPeerPromise) {\n const viewportSlice = this.getViewportSlice();\n this.deleteViewportSlice(viewportSlice, true);\n }\n\n // scrollSaver.save(); // ! slicing will corrupt scroll position\n // const saved = scrollSaver.getSaved();\n // const hadScroll = saved.scrollHeight !== saved.clientHeight;\n\n return {\n restoreScroll: () => {\n log('restore');\n // scrollSaver.restore(_history.length === 1 && !reverse ? false : true);\n scrollSaver.restore(reverse);\n this.onRenderScrollSet(scrollSaver.getSaved());\n },\n scrollSaver\n };\n }\n\n public async performHistoryResult(\n historyResult: HistoryResult | {history: (Message.message | Message.messageService | number)[]},\n reverse: boolean\n ) {\n const log = false ? this.log.bindPrefix('perform-' + (Math.random() * 1000 | 0)) : undefined;\n log?.('start', this.chatInner.parentElement);\n\n let history = historyResult.history;\n history = history.slice(); // need\n\n if(this.needReflowScroll) {\n reflowScrollableElement(this.scrollable.container);\n this.needReflowScroll = false;\n }\n\n const cb = (message: Message.message | Message.messageService) => {\n if(!message) {\n return;\n } else if(message.pFlags.local) {\n return this.processLocalMessageRender(message);\n } else {\n return this.safeRenderMessage(message, reverse);\n }\n };\n\n const messages = await Promise.all(history.map((mid) => {\n return typeof(mid) === 'number' ? this.chat.getMessage(mid) : mid;\n }));\n\n const setLoadedPromises: Promise<any>[] = [];\n if(!this.scrollable.loadedAll['bottom'] || !this.scrollable.loadedAll['top']) {\n let isEnd = (historyResult as HistoryResult).isEnd;\n if(!isEnd) {\n const historyStorage = await this.chat.getHistoryStorage();\n const firstSlice = historyStorage.history.first;\n const lastSlice = historyStorage.history.last;\n isEnd = {top: false, bottom: false, both: false};\n if(firstSlice.isEnd(SliceEnd.Bottom) && (!firstSlice.length || history.includes(firstSlice[0]))) {\n isEnd.bottom = true;\n }\n\n if(lastSlice.isEnd(SliceEnd.Top) && (!lastSlice.length || history.includes(lastSlice[lastSlice.length - 1]))) {\n isEnd.top = true;\n }\n }\n\n if(!isEnd.bottom && this.setPeerOptions) {\n const {lastMsgId, topMessage, savedPosition} = this.setPeerOptions;\n this.setPeerOptions = undefined;\n if((!lastMsgId && !savedPosition) || this.bubbles[topMessage] || lastMsgId === topMessage) {\n isEnd.bottom = true;\n }\n }\n\n if(isEnd.top) setLoadedPromises.push(this.setLoaded('top', true));\n if(isEnd.bottom) setLoadedPromises.push(this.setLoaded('bottom', true));\n }\n\n await Promise.all(setLoadedPromises);\n\n // ! it is important to insert bubbles to group reversed way\n // const length = history.length, promises: Promise<any>[] = [];\n // if(reverse) for(let i = 0; i < length; ++i) promises.push(cb(messages[i]));\n // else for(let i = length - 1; i >= 0; --i) promises.push(cb(messages[i]));\n const promises = messages.map(cb);\n\n // cannot combine them into one promise\n await Promise.all(promises);\n await this.messagesQueuePromise;\n\n if(this.scrollable.loadedAll.top && this.messagesQueueOnRenderAdditional) {\n this.messagesQueueOnRenderAdditional();\n this.messagesQueueOnRenderAdditional?.(); // * can set it second time\n }\n\n log?.('performHistoryResult end');\n }\n\n private onRenderScrollSet(state?: {scrollHeight: number, clientHeight: number}) {\n const className = 'has-sticky-dates';\n if(!this.container.classList.contains(className)) {\n const isLoading = !this.preloader.detached;\n\n if(isLoading ||\n (\n state ??= {\n scrollHeight: this.scrollable.scrollHeight,\n clientHeight: this.scrollable.container.clientHeight\n },\n state.scrollHeight !== state.clientHeight\n )\n ) {\n /* for(const timestamp in this.dateMessages) {\n const dateMessage = this.dateMessages[timestamp];\n dateMessage.div.classList.add('is-sticky');\n } */\n\n const middleware = this.getMiddleware();\n const callback = () => {\n if(!middleware()) return;\n this.container.classList.add(className);\n };\n\n if(this.willScrollOnLoad) {\n callback();\n } else {\n setTimeout(callback, 600);\n }\n\n return;\n }\n }\n\n this.willScrollOnLoad = undefined;\n }\n\n public onDatePick = (timestamp: number) => {\n const peerId = this.peerId;\n this.managers.appMessagesManager.requestHistory(peerId, 0, 2, -1, timestamp, this.chat.threadId).then((history) => {\n if(!history?.messages?.length) {\n this.log.error('no history!');\n return;\n } else if(this.peerId !== peerId) {\n return;\n }\n\n this.chat.setMessageId((history.messages[0] as MyMessage).mid);\n // console.log('got history date:', history);\n });\n };\n\n public requestHistory(maxId: number, loadCount: number, backLimit: number) {\n // const middleware = this.getMiddleware();\n if(this.chat.type === 'chat' || this.chat.type === 'discussion') {\n return this.managers.acknowledged.appMessagesManager.getHistory(this.peerId, maxId, loadCount, backLimit, this.chat.threadId);\n } else if(this.chat.type === 'pinned') {\n return this.managers.acknowledged.appMessagesManager.getSearch({\n peerId: this.peerId,\n inputFilter: {_: 'inputMessagesFilterPinned'},\n maxId,\n limit: loadCount,\n backLimit\n }).then((ackedResult) => {\n return {\n cached: ackedResult.cached,\n result: Promise.resolve(ackedResult.result).then((value) => {\n return {history: value.history.map((m) => m.mid)};\n })\n };\n });\n } else if(this.chat.type === 'scheduled') {\n return this.managers.acknowledged.appMessagesManager.getScheduledMessages(this.peerId).then((ackedResult) => {\n // this.setLoaded('top', true);\n // this.setLoaded('bottom', true);\n return {\n cached: ackedResult.cached,\n result: Promise.resolve(ackedResult.result).then((mids) => ({history: mids.slice().reverse()}))\n };\n });\n }\n }\n\n private async animateAsLadder(additionMsgId: number, additionMsgIds: number[], isAdditionRender: boolean, backLimit: number, maxId: number) {\n /* const middleware = this.getMiddleware();\n await this.ladderDeferred; */\n\n const log = this.log.bindPrefix('ladder');\n if(this.chat.setPeerPromise && !this.resolveLadderAnimation) {\n log.warn('will be delayed');\n // @ts-ignore\n this.resolveLadderAnimation = this.animateAsLadder.bind(this, additionMsgId, additionMsgIds, isAdditionRender, backLimit, maxId);\n return;\n }\n\n /* if(!middleware()) {\n return;\n } */\n\n if(!Object.keys(this.bubbles).length) {\n log.warn('no bubbles');\n return;\n }\n\n let sortedMids = getObjectKeysAndSort(this.bubbles, 'desc');\n\n if(isAdditionRender && additionMsgIds.length) {\n sortedMids = sortedMids.filter((mid) => !additionMsgIds.includes(mid));\n }\n\n let targetMid: number;\n if(backLimit) {\n targetMid = maxId || Math.max(...sortedMids); // * on discussion enter\n } else {\n if(additionMsgId) {\n targetMid = additionMsgId;\n } else { // * if maxId === 0\n targetMid = Math.max(...sortedMids);\n }\n }\n\n const topIds = sortedMids.slice(sortedMids.findIndex((mid) => targetMid > mid));\n const middleIds = isAdditionRender ? [] : [targetMid];\n const bottomIds = isAdditionRender ? [] : sortedMids.slice(0, sortedMids.findIndex((mid) => targetMid >= mid)).reverse();\n\n if(DEBUG) {\n log('targeting mid:', targetMid, maxId, additionMsgId,\n topIds.map((m) => getServerMessageId(m)),\n bottomIds.map((m) => getServerMessageId(m)));\n }\n\n const setBubbles: HTMLElement[] = [];\n\n this.chatInner.classList.add('zoom-fading');\n const delay = isAdditionRender ? 10 : 40;\n const offsetIndex = isAdditionRender ? 0 : 1;\n const animateAsLadder = (mids: number[], offsetIndex = 0) => {\n const animationPromise = deferredPromise<void>();\n let lastMsDelay = 0;\n mids.forEach((mid, idx) => {\n const bubble = this.bubbles[mid];\n if(!bubble || this.skippedMids.has(mid)) {\n log.warn('no bubble by mid:', mid);\n return;\n }\n\n lastMsDelay = ((idx + offsetIndex) || 0.1) * delay;\n // lastMsDelay = (idx + offsetIndex) * delay;\n // lastMsDelay = (idx || 0.1) * 1000;\n\n const contentWrapper = bubble.lastElementChild as HTMLElement;\n const elementsToAnimate: HTMLElement[] = [contentWrapper];\n const item = this.bubbleGroups.getItemByBubble(bubble);\n if(item && item.group.avatar && item.group.lastItem === item) {\n elementsToAnimate.push(item.group.avatar);\n }\n\n elementsToAnimate.forEach((element) => {\n element.classList.add('zoom-fade', 'can-zoom-fade');\n element.style.transitionDelay = lastMsDelay + 'ms';\n });\n\n if(idx === (mids.length - 1)) {\n const onTransitionEnd = (e: TransitionEvent) => {\n if(e.target !== contentWrapper) {\n return;\n }\n\n animationPromise.resolve();\n contentWrapper.removeEventListener('transitionend', onTransitionEnd);\n };\n\n contentWrapper.addEventListener('transitionend', onTransitionEnd);\n }\n\n setBubbles.push(...elementsToAnimate);\n });\n\n if(!mids.length) {\n animationPromise.resolve();\n }\n\n return {lastMsDelay, animationPromise};\n };\n\n const topRes = animateAsLadder(topIds, offsetIndex);\n const middleRes = animateAsLadder(middleIds);\n const bottomRes = animateAsLadder(bottomIds, offsetIndex);\n const promises = [topRes.animationPromise, middleRes.animationPromise, bottomRes.animationPromise];\n const delays: number[] = [topRes.lastMsDelay, middleRes.lastMsDelay, bottomRes.lastMsDelay];\n\n if(this.onAnimateLadder) {\n await this.onAnimateLadder();\n }\n\n fastRaf(() => {\n this.setStickyDateManually(); // ! maybe it's not efficient\n\n setBubbles.forEach((element) => {\n element.classList.remove('zoom-fade');\n });\n });\n\n let promise: Promise<any>;\n if(topIds.length || middleIds.length || bottomIds.length) {\n promise = Promise.all(promises);\n\n dispatchHeavyAnimationEvent(promise, Math.max(...delays) + 200) // * 200 - transition time\n .then(() => {\n fastRaf(() => {\n setBubbles.forEach((element) => {\n element.style.transitionDelay = '';\n element.classList.remove('can-zoom-fade');\n });\n\n this.chatInner.classList.remove('zoom-fading');\n });\n\n // ! в хроме, каким-то образом из-за zoom-fade класса начинает прыгать скролл при подгрузке сообщений вверх,\n // ! т.е. скролл не ставится, так же, как в сафари при translateZ на блок выше scrollable\n // if(!IS_SAFARI) {\n // this.needReflowScroll = true;\n // }\n });\n }\n\n return promise;\n }\n\n private async renderEmptyPlaceholder(\n type: 'group' | 'saved' | 'noMessages' | 'noScheduledMessages' | 'greeting' | 'restricted',\n bubble: HTMLElement,\n message: any,\n elements: (Node | string)[]\n ) {\n const BASE_CLASS = 'empty-bubble-placeholder';\n bubble.classList.add(BASE_CLASS, BASE_CLASS + '-' + type);\n\n let title: HTMLElement;\n if(type === 'group') title = i18n('GroupEmptyTitle1');\n else if(type === 'saved') title = i18n('ChatYourSelfTitle');\n else if(type === 'noMessages' || type === 'greeting') title = i18n('NoMessages');\n else if(type === 'noScheduledMessages') title = i18n('NoScheduledMessages');\n else if(type === 'restricted') {\n title = document.createElement('span');\n title.innerText = await this.managers.appPeersManager.getRestrictionReasonText(this.peerId);\n }\n title.classList.add('center', BASE_CLASS + '-title');\n\n elements.push(title);\n\n let listElements: HTMLElement[];\n if(type === 'group') {\n elements.push(i18n('GroupEmptyTitle2'));\n listElements = [\n i18n('GroupDescription1'),\n i18n('GroupDescription2'),\n i18n('GroupDescription3'),\n i18n('GroupDescription4')\n ];\n } else if(type === 'saved') {\n listElements = [\n i18n('ChatYourSelfDescription1'),\n i18n('ChatYourSelfDescription2'),\n i18n('ChatYourSelfDescription3'),\n i18n('ChatYourSelfDescription4')\n ];\n } else if(type === 'greeting') {\n const subtitle = i18n('NoMessagesGreetingsDescription');\n subtitle.classList.add('center', BASE_CLASS + '-subtitle');\n\n // findAndSplice(this.messagesQueue, q => q.bubble === bubble);\n\n const stickerDiv = document.createElement('div');\n stickerDiv.classList.add(BASE_CLASS + '-sticker');\n\n const middleware = this.getMiddleware();\n\n await this.managers.appStickersManager.getGreetingSticker().then(async(doc) => {\n if(!middleware()) return;\n\n const loadPromises: Promise<any>[] = [];\n await wrapSticker({\n doc,\n // doc: appDocsManager.getDoc(\"5431607541660389336\"), // cubigator mockup\n div: stickerDiv,\n middleware,\n lazyLoadQueue: this.lazyLoadQueue,\n group: this.chat.animationGroup,\n // play: !!message.pending || !multipleRender,\n play: true,\n loop: true,\n withThumb: true,\n loadPromises,\n liteModeKey: 'stickers_chat'\n });\n\n attachClickEvent(stickerDiv, (e) => {\n cancelEvent(e);\n EmoticonsDropdown.onMediaClick({target: e.target});\n });\n\n return Promise.all(loadPromises);\n });\n\n // this.renderMessagesQueue({\n // message,\n // bubble,\n // reverse: false,\n // promises: [loadPromise]\n // });\n\n elements.push(subtitle, stickerDiv);\n }\n\n if(listElements) {\n elements.push(\n ...listElements.map((elem) => {\n const span = document.createElement('span');\n span.classList.add(BASE_CLASS + '-list-item');\n span.append(elem);\n return span;\n })\n );\n\n if(type === 'group') {\n listElements.forEach((elem) => {\n const i = document.createElement('span');\n i.classList.add('tgico-check');\n elem.prepend(i);\n });\n } else if(type === 'saved') {\n listElements.forEach((elem) => {\n const i = document.createElement('span');\n i.classList.add(BASE_CLASS + '-list-bullet');\n i.innerText = '•';\n elem.prepend(i);\n });\n }\n }\n\n if(elements.length > 1) {\n bubble.classList.add('has-description');\n }\n\n elements.forEach((element: any) => element.classList.add(BASE_CLASS + '-line'));\n }\n\n private async processLocalMessageRender(\n message: Message.message | Message.messageService,\n animate?: boolean,\n middleware = this.getMiddleware()\n ) {\n const isSponsored = !!(message as Message.message).pFlags.sponsored;\n const m = middlewarePromise(middleware);\n\n const p: Parameters<ChatBubbles['safeRenderMessage']>[4] = async(result) => {\n const {bubble} = await m(result);\n if(!bubble) {\n return result;\n }\n\n (bubble as any).message = message;\n\n bubble.classList.add('is-group-last', 'is-group-first');\n\n const updatePosition = () => {\n if(this.updatePlaceholderPosition === updatePosition) {\n this.updatePlaceholderPosition = undefined;\n }\n\n appendTo[method](bubble);\n };\n\n if(!isSponsored) {\n bubble.classList.add('bubble-first');\n bubble.classList.remove('can-have-tail', 'is-in');\n }\n\n const elements: (Node | string)[] = [];\n const isBot = this.chat.isBot;\n let renderPromise: Promise<any>, appendTo = this.container, method: 'append' | 'prepend' = 'append';\n if(this.chat.isRestricted) {\n renderPromise = this.renderEmptyPlaceholder('restricted', bubble, message, elements);\n } else if(isSponsored) {\n let text: LangPackKey, mid: number, startParam: string, callback: () => void;\n\n bubble.classList.add('avoid-selection');\n bubble.style.order = '999999';\n\n const sponsoredMessage = this.sponsoredMessage = (message as Message.message).sponsoredMessage;\n const peerId = getPeerId(sponsoredMessage.from_id);\n // const peer = this.appPeersManager.getPeer(peerId);\n if(sponsoredMessage.channel_post) {\n text = 'OpenChannelPost';\n mid = generateMessageId(sponsoredMessage.channel_post);\n } else if(sponsoredMessage.start_param || isBot) {\n text = 'Chat.Message.ViewBot';\n startParam = sponsoredMessage.start_param;\n } else {\n text = await this.managers.appPeersManager.isAnyGroup(peerId) ? 'Chat.Message.ViewGroup' : 'Chat.Message.ViewChannel';\n }\n\n if(sponsoredMessage.chat_invite) {\n callback = () => {\n PopupElement.createPopup(PopupJoinChatInvite, sponsoredMessage.chat_invite_hash, sponsoredMessage.chat_invite as ChatInvite.chatInvite);\n };\n } else if(sponsoredMessage.chat_invite_hash) {\n callback = () => {\n const link: InternalLink = {\n _: INTERNAL_LINK_TYPE.JOIN_CHAT,\n invite: sponsoredMessage.chat_invite_hash\n };\n\n this.chat.appImManager.processInternalLink(link);\n };\n } else {\n callback = () => {\n this.chat.appImManager.setInnerPeer({\n peerId,\n lastMsgId: mid,\n startParam\n });\n };\n }\n\n const button = this.makeViewButton({text});\n\n this.observer.observe(button, this.viewsObserverCallback);\n\n if(callback) {\n attachClickEvent(button, callback);\n }\n\n bubble.querySelector('.bubble-content').prepend(button);\n\n appendTo = this.chatInner;\n method = 'append';\n animate = false;\n\n // return result;\n } else if(isBot && message._ === 'message') {\n const b = document.createElement('b');\n b.append(i18n('BotInfoTitle'));\n elements.push(b, '\\n\\n');\n appendTo = this.chatInner;\n method = 'prepend';\n } else if(this.chat.isAnyGroup && ((await m(this.managers.appPeersManager.getPeer(this.peerId))) as MTChat.chat).pFlags.creator) {\n renderPromise = this.renderEmptyPlaceholder('group', bubble, message, elements);\n } else if(this.chat.type === 'scheduled') {\n renderPromise = this.renderEmptyPlaceholder('noScheduledMessages', bubble, message, elements);\n } else if(rootScope.myId === this.peerId) {\n renderPromise = this.renderEmptyPlaceholder('saved', bubble, message, elements);\n } else if(this.peerId.isUser() && !isBot && await m(this.chat.canSend()) && this.chat.type === 'chat') {\n renderPromise = this.renderEmptyPlaceholder('greeting', bubble, message, elements);\n } else {\n renderPromise = this.renderEmptyPlaceholder('noMessages', bubble, message, elements);\n }\n\n if(renderPromise) {\n await renderPromise;\n }\n\n if(elements.length) {\n const messageDiv = bubble.querySelector('.message, .service-msg');\n messageDiv.prepend(...elements);\n }\n\n const isWaitingForAnimation = !!this.messagesQueueOnRenderAdditional;\n const noTransition = this.setPeerCached && !isWaitingForAnimation;\n if(noTransition) {\n const setOn = bubble.firstElementChild;\n setOn.classList.add('no-transition');\n\n if(this.chat.setPeerPromise) {\n this.chat.setPeerPromise.catch(noop).finally(() => {\n setOn.classList.remove('no-transition');\n });\n }\n }\n\n if(animate === undefined && !noTransition) {\n animate = true;\n }\n\n if(isWaitingForAnimation || animate) {\n this.updatePlaceholderPosition = updatePosition;\n\n this.onAnimateLadder = () => {\n // appendTo[method](bubble);\n this.onAnimateLadder = undefined;\n\n // need raf here because animation won't fire if this message is single\n if(!this.messagesQueuePromise) {\n return fastRafPromise();\n }\n };\n } else if(this.chat.setPeerPromise) {\n this.attachPlaceholderOnRender = () => {\n this.attachPlaceholderOnRender = undefined;\n updatePosition();\n // appendTo[method](bubble);\n };\n } else {\n this.updatePlaceholderPosition = updatePosition;\n // appendTo[method](bubble);\n }\n\n if(!isWaitingForAnimation && animate) {\n await m(getHeavyAnimationPromise());\n const additionMsgIds = getObjectKeysAndSort(this.bubbles);\n indexOfAndSplice(additionMsgIds, message.mid);\n this.animateAsLadder(message.mid, additionMsgIds, false, 0, 0);\n }\n\n bubble.middlewareHelper.onDestroy(() => {\n if(this.emptyPlaceholderBubble === bubble) {\n this.emptyPlaceholderBubble = undefined;\n }\n });\n\n this.emptyPlaceholderBubble = bubble;\n\n return result;\n };\n\n return this.safeRenderMessage(\n message,\n !isSponsored,\n undefined,\n false,\n p\n );\n }\n\n private makeViewButton<T extends Parameters<typeof Button>[1]>(options: T) {\n return Button('btn-primary btn-primary-transparent bubble-view-button', options);\n }\n\n private generateLocalMessageId(addOffset = 0) {\n // const INCREMENT = 0x10;\n const offset = (this.chat.type === 'scheduled' ? -1 : 0) + addOffset;\n // offset = generateMessageId(offset);\n // id: -Math.abs(+this.peerId * INCREMENT + offset),\n const id = -Math.abs(offset);\n const mid = -Math.abs(generateMessageId(id));\n return {id, mid};\n }\n\n private async generateLocalFirstMessage<T extends boolean>(service?: T, fill?: (message: GenerateLocalMessageType<T>) => void, addOffset = 0): Promise<GenerateLocalMessageType<T>> {\n const {id, mid} = this.generateLocalMessageId(addOffset);\n let message: Omit<Message.message | Message.messageService, 'message'> & {message?: string} = {\n _: service ? 'messageService' : 'message',\n date: 0,\n id,\n mid,\n peer_id: await this.managers.appPeersManager.getOutputPeer(this.peerId),\n pFlags: {\n local: true\n }\n };\n\n if(!service) {\n message.message = '';\n }/* else {\n (message as Message.messageService).action = {} as any;\n } */\n\n assumeType<GenerateLocalMessageType<T>>(message);\n\n fill && fill(message);\n\n const savedMessages = await this.managers.appMessagesManager.saveMessages([message], {storage: new Map() as any});\n message = savedMessages[0];\n message.mid = mid;\n return message as any;\n }\n\n public getViewportSlice() {\n // this.log.trace('viewport slice');\n return getViewportSlice({\n overflowElement: this.scrollable.container,\n selector: '.bubbles-date-group .bubble:not(.is-date)',\n extraSize: Math.max(700, windowSize.height) * 2\n });\n }\n\n public deleteViewportSlice(slice: ReturnType<ChatBubbles['getViewportSlice']>, ignoreScrollSaving?: boolean) {\n if(DO_NOT_SLICE_VIEWPORT_ON_RENDER) {\n return;\n }\n\n const {invisibleTop, invisibleBottom} = slice;\n const invisible = invisibleTop.concat(invisibleBottom);\n if(!invisible.length) {\n return;\n }\n\n if(invisibleTop.length) {\n this.setLoaded('top', false);\n this.getHistoryTopPromise = undefined;\n }\n\n if(invisibleBottom.length) {\n this.setLoaded('bottom', false);\n this.getHistoryBottomPromise = undefined;\n }\n\n const mids = invisible.map(({element}) => +element.dataset.mid);\n\n let scrollSaver: ScrollSaver;\n if(/* !!invisibleTop.length !== !!invisibleBottom.length && */!ignoreScrollSaving) {\n scrollSaver = this.createScrollSaver(!!invisibleTop.length);\n scrollSaver.save();\n }\n\n this.deleteMessagesByIds(mids, false, true);\n\n if(scrollSaver) {\n scrollSaver.restore();\n } else if(invisibleTop.length) {\n this.scrollable.lastScrollPosition = this.scrollable.scrollTop;\n }\n }\n\n public sliceViewport(ignoreHeavyAnimation?: boolean) {\n // Safari cannot reset the scroll.\n if(IS_SAFARI || (this.isHeavyAnimationInProgress && !ignoreHeavyAnimation) || DO_NOT_SLICE_VIEWPORT) {\n return;\n }\n\n // const scrollSaver = new ScrollSaver(this.scrollable, true);\n // scrollSaver.save();\n const slice = this.getViewportSlice();\n // if(IS_SAFARI) slice.invisibleTop = [];\n this.deleteViewportSlice(slice);\n // scrollSaver.restore();\n }\n\n private async setLoaded(side: SliceSides, value: boolean, checkPlaceholders = true) {\n const willChange = this.scrollable.loadedAll[side] !== value;\n if(!willChange) {\n return;\n }\n\n const log = this.log.bindPrefix('setLoaded');\n log('change', side, value);\n\n this.scrollable.loadedAll[side] = value;\n this.scrollable.onScroll(); // ! WARNING\n // return;\n\n if(!checkPlaceholders) {\n return;\n }\n\n if(!this.chat.isRestricted) {\n if(side === 'bottom' && this.chat.isBroadcast/* && false */) {\n this.toggleSponsoredMessage(value);\n }\n\n if(side === 'top' && value && this.chat.isBot) {\n return this.renderBotPlaceholder();\n }\n }\n\n return this.checkIfEmptyPlaceholderNeeded();\n }\n\n private async toggleSponsoredMessage(value: boolean) {\n const log = this.log.bindPrefix('sponsored');\n log('checking');\n const {mid} = this.generateLocalMessageId(SPONSORED_MESSAGE_ID_OFFSET);\n if(value) {\n const middleware = this.getMiddleware(() => {\n return this.scrollable.loadedAll.bottom && this.getSponsoredMessagePromise === promise;\n });\n\n const promise = this.getSponsoredMessagePromise = this.managers.appChatsManager.getSponsoredMessage(this.peerId.toChatId())\n .then(async(sponsoredMessages) => {\n if(!middleware() || sponsoredMessages._ === 'messages.sponsoredMessagesEmpty') {\n return;\n }\n\n const sponsoredMessage = sponsoredMessages.messages[0];\n if(!sponsoredMessage) {\n log('no message');\n return;\n }\n\n const messagePromise = this.generateLocalFirstMessage(false, (message) => {\n message.message = sponsoredMessage.message;\n message.from_id = sponsoredMessage.from_id;\n message.entities = sponsoredMessage.entities;\n message.pFlags.sponsored = true;\n message.sponsoredMessage = sponsoredMessage;\n }, SPONSORED_MESSAGE_ID_OFFSET);\n\n return Promise.all([\n messagePromise,\n this.getHistoryTopPromise, // wait for top load and execute rendering after or with it\n this.messagesQueuePromise\n ]).then(([message]) => {\n if(!middleware()) return;\n // this.processLocalMessageRender(message);\n log('rendering', message);\n return this.performHistoryResult({history: [message]}, false);\n });\n }).finally(() => {\n if(this.getSponsoredMessagePromise === promise) {\n this.getSponsoredMessagePromise = undefined;\n }\n });\n } else {\n log('clearing rendered', mid);\n this.getSponsoredMessagePromise = undefined;\n this.deleteMessagesByIds([mid]);\n }\n }\n\n private async renderBotPlaceholder() {\n const _log = this.log.bindPrefix('bot placeholder');\n\n const middleware = this.getMiddleware();\n const result = await this.managers.acknowledged.appProfileManager.getProfile(this.peerId.toUserId());\n _log('getting profile, cached:', result.cached);\n const processPromise = result.result.then(async(userFull) => {\n if(!middleware()) {\n return;\n }\n\n if(!userFull.bot_info?.description) {\n _log.warn('no description');\n return this.checkIfEmptyPlaceholderNeeded();\n }\n\n const message = await this.generateLocalFirstMessage(false, (message) => {\n const botInfo = userFull.bot_info;\n message.message = botInfo.description;\n if(botInfo.description_document) message.media = {_: 'messageMediaDocument', document: botInfo.description_document, pFlags: {}};\n if(botInfo.description_photo) message.media = {_: 'messageMediaPhoto', photo: botInfo.description_photo, pFlags: {}};\n });\n\n if(!middleware()) {\n return;\n }\n\n _log('rendering');\n const renderPromise = this.processLocalMessageRender(message, !result.cached).then(() => {\n _log('done');\n });\n\n return {renderPromise};\n });\n\n if(!result.cached) {\n return;\n }\n\n return processPromise;\n }\n\n public async checkIfEmptyPlaceholderNeeded() {\n if(this.scrollable.loadedAll.top &&\n this.scrollable.loadedAll.bottom &&\n this.emptyPlaceholderBubble === undefined &&\n (\n this.chat.isRestricted ||\n !(await this.chat.getHistoryStorage()).count ||\n (\n // !Object.keys(this.bubbles).length ||\n // ! WARNING ! ! ! ! ! ! REPLACE LINE ABOVE WITH THESE\n Object.keys(this.bubbles).length &&\n !this.getRenderedLength()\n ) ||\n (this.chat.type === 'scheduled' && !Object.keys(this.bubbles).length)\n )\n ) {\n this.log('inject empty peer placeholder');\n\n const message = await this.generateLocalFirstMessage(true);\n return {renderPromise: this.processLocalMessageRender(message)};\n }\n }\n\n public getHistory1(maxId?: number, reverse?: boolean, isBackLimit?: boolean, additionMsgId?: number, justLoad?: boolean) {\n const middleware = this.getMiddleware(justLoad ? undefined : () => {\n return (reverse ? this.getHistoryTopPromise : this.getHistoryBottomPromise) === waitPromise;\n });\n\n const result = this.getHistory(maxId, reverse, isBackLimit, additionMsgId, justLoad, middleware);\n const waitPromise = result.then((res) => res && (res.waitPromise || res.promise));\n\n (reverse ? this.getHistoryTopPromise = waitPromise : this.getHistoryBottomPromise = waitPromise);\n waitPromise.then(() => {\n if(!middleware()) {\n return;\n }\n\n (reverse ? this.getHistoryTopPromise = undefined : this.getHistoryBottomPromise = undefined);\n\n if(!justLoad) {\n // preload more\n // if(!isFirstMessageRender) {\n if(this.chat.type === 'chat'/* || this.chat.type === 'discussion' */) {\n /* const storage = this.appMessagesManager.getHistoryStorage(peerId, this.chat.threadId);\n const isMaxIdInHistory = storage.history.indexOf(maxId) !== -1;\n if(isMaxIdInHistory || true) { // * otherwise it is a search or jump */\n setTimeout(() => {\n if(reverse) {\n this.loadMoreHistory(true, true);\n } else {\n this.loadMoreHistory(false, true);\n }\n }, 0);\n // }\n }\n // }\n\n // this.scrollable.onScroll();\n }\n });\n\n return result;\n }\n\n // private async getDiscussionMessages() {\n // const mids = await this.chat.getMidsByMid(this.chat.threadId);\n // return Promise.all(mids.map((mid) => this.chat.getMessage(mid)));\n // }\n\n /**\n * Load and render history\n * @param maxId max message id\n * @param reverse 'true' means up\n * @param isBackLimit is search\n * @param additionMsgId for the last message\n * @param justLoad do not render\n */\n public async getHistory(\n maxId = 0,\n reverse = false,\n isBackLimit = false,\n additionMsgId = 0,\n justLoad = false,\n middleware?: () => boolean\n ): Promise<{cached: boolean, promise: Promise<void>, waitPromise: Promise<any>}> {\n const peerId = this.peerId;\n\n const isBroadcast = this.chat.isBroadcast;\n // console.time('appImManager call getHistory');\n const pageCount = Math.min(30, windowSize.height / 40/* * 1.25 */ | 0);\n // const loadCount = Object.keys(this.bubbles).length > 0 ? 50 : pageCount;\n const realLoadCount = isBroadcast ? 20 : (Object.keys(this.bubbles).length > 0 ? Math.max(35, pageCount) : pageCount);\n // const realLoadCount = pageCount;//const realLoadCount = 50;\n let loadCount = realLoadCount;\n\n /* if(TEST_SCROLL) {\n //loadCount = 1;\n if(Object.keys(this.bubbles).length > 0)\n return {cached: false, promise: Promise.resolve(true)};\n } */\n if(TEST_SCROLL !== undefined) {\n if(TEST_SCROLL) {\n if(Object.keys(this.bubbles).length > 0) {\n --TEST_SCROLL;\n }\n } else {\n return {cached: false, promise: Promise.resolve(), waitPromise: Promise.resolve()};\n }\n }\n\n // //console.time('render history total');\n\n let backLimit = 0;\n if(isBackLimit) {\n backLimit = loadCount;\n\n if(!reverse) { // if not jump\n loadCount = 0;\n // maxId = this.appMessagesManager.incrementMessageId(maxId, 1);\n }\n }\n\n let additionMsgIds: number[];\n if(additionMsgId && !isBackLimit) {\n if(this.chat.type === 'pinned') {\n additionMsgIds = [additionMsgId];\n } else {\n const historyStorage = await this.chat.getHistoryStorage();\n const slice = historyStorage.history.slice;\n if(slice.length < loadCount && !slice.isEnd(SliceEnd.Both)) {\n additionMsgIds = slice.slice();\n\n // * filter last album, because we don't know is it the last item\n for(let i = additionMsgIds.length - 1; i >= 0; --i) {\n const message = await this.chat.getMessage(additionMsgIds[i]);\n if((message as Message.message)?.grouped_id) additionMsgIds.splice(i, 1);\n else break;\n }\n\n maxId = additionMsgIds[additionMsgIds.length - 1] || maxId;\n }\n }\n }\n\n /* const result = additionMsgID ?\n {history: [additionMsgID]} :\n appMessagesManager.getHistory(this.peerId, maxId, loadCount, backLimit); */\n let result: AckedResult<MyHistoryResult> = await this.requestHistory(maxId, loadCount, backLimit) as any;\n let resultPromise: typeof result['result'];\n\n this.log('i vin brehnya', result, maxId, loadCount, backLimit);\n\n // const isFirstMessageRender = !!additionMsgID && result.cached && !appMessagesManager.getMessage(additionMsgID).grouped_id;\n const isAdditionRender = additionMsgIds?.length && !result.cached;\n const isFirstMessageRender = (this.isFirstLoad && backLimit && !result.cached) || isAdditionRender;\n if(isAdditionRender) {\n resultPromise = result.result;\n\n result = {\n cached: true,\n result: Promise.resolve({history: additionMsgIds})\n };\n\n // additionMsgID = 0;\n }\n\n this.isFirstLoad = false;\n\n const processResult = async(historyResult: Awaited<typeof result['result']>) => {\n if((historyResult as HistoryResult).isEnd?.top) {\n if(this.chat.type === 'discussion') { // * inject discussion start\n const serviceStartMessageId = await this.managers.appMessagesManager.getThreadServiceMessageId(this.peerId, this.chat.threadId);\n if(serviceStartMessageId) historyResult.history.push(serviceStartMessageId);\n const mids = await this.chat.getMidsByMid(this.chat.threadId);\n historyResult.history.push(...mids.reverse());\n }\n\n // synchronize bot placeholder appearance\n await this.managers.appProfileManager.getProfileByPeerId(peerId);\n\n // await this.setLoaded('top', true);\n }\n };\n\n const sup = (historyResult: Awaited<typeof result['result']>) => {\n return getHeavyAnimationPromise().then(() => {\n return processResult(historyResult);\n }).then(() => {\n if(!isAdditionRender && additionMsgId) {\n historyResult.history.unshift(additionMsgId);\n }\n\n return this.performHistoryResult(historyResult, reverse);\n });\n };\n\n const processPromise = (_promise: typeof result['result']) => {\n const promise = Promise.resolve(_promise).then((result) => {\n if(middleware && !middleware()) {\n throw PEER_CHANGED_ERROR;\n }\n\n if(justLoad) {\n // нужно делать из-за ранней прогрузки\n this.scrollable.onScroll();\n // fastRaf(() => {\n // this.scrollable.checkForTriggers();\n // });\n return;\n }\n\n return sup(result);\n }, (err) => {\n this.log.error('getHistory error:', err);\n throw err;\n });\n\n return promise;\n };\n\n let promise: Promise<void>, cached: boolean;\n if(!result.cached) {\n cached = false;\n promise = processPromise(result.result);\n } else if(justLoad) {\n // нужно делать из-за ранней прогрузки\n this.scrollable.onScroll();\n return null;\n } else {\n cached = true;\n promise = sup(await result.result);\n }\n\n const waitPromise = isAdditionRender ? processPromise(resultPromise) : promise;\n\n if(isFirstMessageRender && liteMode.isAvailable('animations')/* && false */) {\n let times = isAdditionRender ? 2 : 1;\n this.messagesQueueOnRenderAdditional = () => {\n this.log('messagesQueueOnRenderAdditional');\n\n if(--times) return;\n\n this.messagesQueueOnRenderAdditional = undefined;\n\n const promise = this.animateAsLadder(additionMsgId, additionMsgIds, isAdditionRender, backLimit, maxId);\n promise.then(() => {\n setTimeout(() => { // preload messages\n this.loadMoreHistory(reverse, true);\n }, 0);\n });\n };\n } else {\n this.messagesQueueOnRenderAdditional = undefined;\n }\n\n if(justLoad) {\n return null;\n }\n\n return {cached, promise, waitPromise};\n }\n\n public async setUnreadDelimiter() {\n if(!(this.chat.type === 'chat' || this.chat.type === 'discussion')) {\n return;\n }\n\n if(this.attachedUnreadBubble) {\n return;\n }\n\n const historyMaxId = await this.chat.getHistoryMaxId();\n let readMaxId = await this.managers.appMessagesManager.getReadMaxIdIfUnread(this.peerId, this.chat.threadId);\n if(!readMaxId) return;\n\n readMaxId = Object.keys(this.bubbles)\n .filter((mid) => !this.bubbles[mid].classList.contains('is-out'))\n .map((i) => +i)\n .sort((a, b) => a - b)\n .find((i) => i > readMaxId);\n\n if(readMaxId && this.bubbles[readMaxId]) {\n const bubble = this.bubbles[readMaxId];\n if(this.firstUnreadBubble && this.firstUnreadBubble !== bubble) {\n this.firstUnreadBubble.classList.remove('is-first-unread');\n this.firstUnreadBubble = null;\n }\n\n if(readMaxId !== historyMaxId) {\n bubble.classList.add('is-first-unread');\n }\n\n this.firstUnreadBubble = bubble;\n this.attachedUnreadBubble = true;\n }\n }\n\n public deleteEmptyDateGroups() {\n const mustBeCount = this.stickyIntersector ? STICKY_OFFSET : 1;\n let deleted = false;\n for(const i in this.dateMessages) {\n const dateMessage = this.dateMessages[i];\n\n if(dateMessage.container.childElementCount === mustBeCount) { // only date div + sentinel div\n dateMessage.container.remove();\n if(this.stickyIntersector) {\n this.stickyIntersector.unobserve(dateMessage.container, dateMessage.div);\n }\n delete this.dateMessages[i];\n deleted = true;\n\n // * no sense in it\n /* if(dateMessage.div === this.previousStickyDate) {\n this.previousStickyDate = undefined;\n } */\n }\n }\n\n if(!deleted) {\n return;\n }\n\n if(!Object.keys(this.dateMessages).length) {\n this.container.classList.remove('has-groups');\n }\n\n this.checkIfEmptyPlaceholderNeeded();\n this.setStickyDateManually();\n }\n}\n\nexport function generateTail() {\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.setAttributeNS(null, 'viewBox', '0 0 11 20');\n svg.setAttributeNS(null, 'width', '11');\n svg.setAttributeNS(null, 'height', '20');\n svg.classList.add('bubble-tail');\n\n const use = document.createElementNS('http://www.w3.org/2000/svg', 'use');\n use.setAttributeNS(null, 'href', '#message-tail-filled');\n\n svg.append(use);\n\n return svg;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {copyTextToClipboard} from '../clipboard';\n// import SelectionSaver from \"../selectionSaver\";\n// import selectElementContents from \"./selectElementContents\";\n\nexport default function copyFromElement(element: HTMLElement) {\n copyTextToClipboard(element.textContent);\n // const saver = new SelectionSaver();\n // saver.save();\n // selectElementContents(element);\n // document.execCommand('copy');\n // saver.restore();\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {Middleware} from '../../helpers/middleware';\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport lottieLoader, {LottieAssetName} from '../../lib/rlottie/lottieLoader';\nimport RLottiePlayer from '../../lib/rlottie/rlottiePlayer';\nimport rootScope from '../../lib/rootScope';\nimport wrapSticker from './sticker';\n\nexport default async function wrapLocalSticker({\n emoji,\n width,\n height,\n assetName,\n middleware,\n managers = rootScope.managers,\n loop = false,\n autoplay = true\n}: {\n doc?: MyDocument,\n // url?: string,\n emoji?: string,\n assetName?: LottieAssetName,\n width: number,\n height: number,\n managers?: AppManagers,\n middleware?: Middleware,\n autoplay?: boolean,\n loop?: false\n}) {\n const container = document.createElement('div');\n container.classList.add('media-sticker-wrapper');\n\n let playerPromise: Promise<RLottiePlayer>;\n if(assetName) {\n playerPromise = lottieLoader.loadAnimationAsAsset({\n container,\n loop,\n autoplay,\n width,\n height,\n noCache: true,\n middleware\n }, assetName).then((animation) => {\n return lottieLoader.waitForFirstFrame(animation);\n });\n } else if(emoji) {\n const doc = await managers.appStickersManager.getAnimatedEmojiSticker(emoji);\n if(doc) playerPromise = wrapSticker({\n doc,\n div: container,\n loop,\n play: autoplay,\n width,\n height,\n emoji,\n managers,\n middleware\n }).then((result) => {\n return result.render as Promise<RLottiePlayer>;\n });\n }\n\n return {container, promise: playerPromise};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport {MediaSizeType} from '../../helpers/mediaSizes';\nimport {Message} from '../../layer';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getMediaDurationFromMessage from '../../lib/appManagers/utils/messages/getMediaDurationFromMessage';\nimport wrapRichText from '../../lib/richTextProcessor/wrapRichText';\nimport {MediaSearchContext} from '../appMediaPlaybackController';\nimport Chat from '../chat/chat';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport wrapDocument from './document';\n\nexport default async function wrapGroupedDocuments({\n albumMustBeRenderedFull,\n message,\n bubble,\n messageDiv,\n chat,\n loadPromises,\n autoDownloadSize,\n lazyLoadQueue,\n searchContext,\n useSearch,\n sizeType,\n managers,\n fontWeight,\n fontSize,\n richTextFragment,\n richTextOptions,\n canTranscribeVoice\n}: {\n albumMustBeRenderedFull: boolean,\n message: any,\n messageDiv: HTMLElement,\n bubble: HTMLElement,\n uploading?: boolean,\n chat: Chat,\n loadPromises?: Promise<any>[],\n autoDownloadSize?: number,\n lazyLoadQueue?: LazyLoadQueue,\n searchContext?: MediaSearchContext,\n useSearch?: boolean,\n sizeType?: MediaSizeType,\n managers?: AppManagers,\n fontWeight?: number,\n fontSize?: number,\n richTextFragment?: DocumentFragment,\n richTextOptions?: Parameters<typeof wrapRichText>[1]\n canTranscribeVoice?: boolean\n}) {\n let nameContainer: HTMLElement;\n const mids = albumMustBeRenderedFull ? await chat.getMidsByMid(message.mid) : [message.mid];\n /* if(isPending) {\n mids.reverse();\n } */\n\n const promises = mids.map(async(mid, idx) => {\n const message = (await chat.getMessage(mid)) as Message.message;\n const div = await wrapDocument({\n message,\n loadPromises,\n autoDownloadSize,\n lazyLoadQueue,\n searchContext,\n sizeType,\n managers,\n fontWeight,\n fontSize,\n canTranscribeVoice\n });\n\n const container = document.createElement('div');\n container.classList.add('document-container');\n container.dataset.mid = '' + mid;\n container.dataset.peerId = '' + message.peerId;\n\n const wrapper = document.createElement('div');\n wrapper.classList.add('document-wrapper');\n\n if(message.message) {\n const messageDiv = document.createElement('div');\n messageDiv.classList.add('document-message');\n\n let fragment = richTextFragment;\n if(!fragment) {\n fragment = wrapRichText(message.message, {\n ...richTextOptions,\n entities: message.totalEntities,\n maxMediaTimestamp: getMediaDurationFromMessage(message)\n });\n }\n\n setInnerHTML(messageDiv, fragment);\n\n wrapper.append(messageDiv);\n }\n\n if(mids.length > 1) {\n const selection = document.createElement('div');\n selection.classList.add('document-selection');\n container.append(selection);\n\n container.classList.add('grouped-item');\n\n if(idx === 0) {\n nameContainer = wrapper;\n }\n }\n\n wrapper.append(div);\n container.append(wrapper);\n return container;\n });\n\n const containers = await Promise.all(promises);\n messageDiv.append(...containers);\n\n if(mids.length > 1) {\n bubble.classList.add('is-multiple-documents', 'is-grouped');\n }\n\n return nameContainer;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport rootScope from '../../lib/rootScope';\nimport PollElement from '../poll';\n\nexport default function wrapPoll(message: any, managers: AppManagers = rootScope.managers) {\n const elem = new PollElement();\n elem.message = message;\n elem.managers = managers;\n elem.setAttribute('peer-id', '' + message.peerId);\n elem.setAttribute('poll-id', message.media.poll.id);\n elem.setAttribute('message-id', '' + message.mid);\n elem.render();\n return elem;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {ReportReason} from '../../layer';\nimport InputField from '../inputField';\nimport {toastNew} from '../toast';\nimport wrapStickerEmoji from '../wrappers/stickerEmoji';\nimport PopupPeer from './peer';\n\nexport default class PopupReportMessagesConfirm extends PopupPeer {\n public static STICKER_EMOJI = '👮‍♀️';\n constructor(peerId: PeerId, mids: number[], reason: ReportReason['_'], onConfirm?: () => void) {\n super('popup-report-messages-confirm', {\n noTitle: true,\n descriptionLangKey: 'ReportInfo',\n buttons: [{\n langKey: 'ReportChat',\n callback: () => {\n if(!inputField.isValid()) {\n return;\n }\n\n onConfirm && onConfirm();\n this.managers.appMessagesManager.reportMessages(peerId, mids, reason, inputField.value).then((bool) => {\n if(!bool) return;\n\n toastNew({\n langPackKey: 'ReportSentInfo'\n });\n });\n }\n }],\n body: true\n });\n\n const div = document.createElement('div');\n const size = 100;\n wrapStickerEmoji({\n div,\n emoji: PopupReportMessagesConfirm.STICKER_EMOJI,\n width: size,\n height: size\n }).then(({render}) => render).finally(() => {\n this.show();\n });\n\n this.header.replaceWith(div);\n\n const inputField = new InputField({\n label: 'ReportHint',\n maxLength: 512,\n placeholder: 'ReportChatDescription'\n });\n\n inputField.input.addEventListener('input', () => {\n this.buttons[0].element.toggleAttribute('disabled', !inputField.isValid());\n });\n\n this.body.append(inputField.container);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '.';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport whichChild from '../../helpers/dom/whichChild';\nimport preloadAnimatedEmojiSticker from '../../helpers/preloadAnimatedEmojiSticker';\nimport {ReportReason} from '../../layer';\nimport {LangPackKey} from '../../lib/langPack';\nimport Button from '../button';\nimport PopupPeer from './peer';\nimport PopupReportMessagesConfirm from './reportMessagesConfirm';\n\nexport default class PopupReportMessages extends PopupPeer {\n constructor(peerId: PeerId, mids: number[], onConfirm?: () => void) {\n super('popup-report-messages', {titleLangKey: 'ChatTitle.ReportMessages', buttons: [], body: true});\n\n mids = mids.slice();\n\n const buttons: [LangPackKey, ReportReason['_']][] = [\n ['ReportChatSpam', 'inputReportReasonSpam'],\n ['ReportChatViolence', 'inputReportReasonViolence'],\n ['ReportChatChild', 'inputReportReasonChildAbuse'],\n ['ReportChatPornography', 'inputReportReasonPornography'],\n ['ReportChatOther', 'inputReportReasonOther'],\n ['ReportChatPersonalDetails', 'inputReportReasonPersonalDetails'],\n ['ReportChatIllegalDrugs', 'inputReportReasonIllegalDrugs']\n ];\n\n const className = 'btn-primary btn-transparent';\n buttons.forEach((b) => {\n const button = Button(className, {/* icon: 'edit', */text: b[0]});\n this.body.append(button);\n });\n\n const preloadStickerPromise = preloadAnimatedEmojiSticker(PopupReportMessagesConfirm.STICKER_EMOJI);\n\n attachClickEvent(this.body, (e) => {\n const target = findUpClassName(e.target, 'btn-primary');\n const reason = buttons[whichChild(target)][1];\n\n preloadStickerPromise.then(() => {\n this.hide();\n\n PopupElement.createPopup(PopupReportMessagesConfirm, peerId, mids, reason, onConfirm);\n });\n }, {listenerSetter: this.listenerSetter});\n\n // this.body.style.margin = '0 -1rem';\n this.buttonsEl.style.marginTop = '.5rem';\n\n this.show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport I18n, {i18n} from '../../lib/langPack';\nimport PopupPeer from './peer';\n\nexport default class PopupSponsored extends PopupPeer {\n constructor() {\n super('popup-sponsored', {\n titleLangKey: 'Chat.Message.Sponsored.What',\n descriptionLangKey: 'Chat.Message.Ad.Text',\n descriptionLangArgs: [i18n('Chat.Message.Sponsored.Link')],\n buttons: [{\n langKey: 'OK',\n isCancel: true\n }, {\n langKey: 'Chat.Message.Ad.ReadMore',\n callback: () => {\n window.open(I18n.format('Chat.Message.Sponsored.Link', true));\n },\n isCancel: true\n }],\n scrollable: true\n });\n\n this.scrollable.append(this.description);\n\n this.show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '.';\nimport {Message, Reaction} from '../../layer';\nimport ReactionsElement from '../chat/reactions';\nimport {horizontalMenu} from '../horizontalMenu';\nimport Scrollable from '../scrollable';\nimport ScrollableLoader from '../../helpers/scrollableLoader';\nimport appDialogsManager from '../../lib/appManagers/appDialogsManager';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport wrapSticker from '../wrappers/sticker';\nimport ReactionElement from '../chat/reaction';\nimport getUserStatusString from '../wrappers/getUserStatusString';\nimport {makeMediaSize} from '../../helpers/mediaSize';\nimport wrapCustomEmoji from '../wrappers/customEmoji';\nimport SettingSection from '../settingSection';\nimport {formatFullSentTime} from '../../helpers/date';\n\nexport default class PopupReactedList extends PopupElement {\n constructor(\n private message: Message.message\n ) {\n super('popup-reacted-list', {closable: true, overlayClosable: true, body: true});\n\n this.init();\n }\n\n private async init() {\n const middleware = this.middlewareHelper.get();\n const message = await this.managers.appMessagesManager.getGroupsFirstMessage(this.message);\n if(!middleware()) return;\n const canViewReadParticipants = await this.managers.appMessagesManager.canViewMessageReadParticipants(message);\n if(!middleware()) return;\n // this.body.append(generateDelimiter());\n\n const reactionsElement = new ReactionsElement();\n const newMessage: Message.message = {\n ...message,\n mid: 0,\n id: 0,\n reactions: {\n _: 'messageReactions',\n results: [],\n\n ...message.reactions,\n\n pFlags: {},\n recent_reactions: []\n }\n };\n\n newMessage.reactions.results = newMessage.reactions.results.map((reactionCount) => {\n return {\n ...reactionCount,\n chosen_order: undefined,\n pFlags: {}\n };\n });\n\n reactionsElement.init(newMessage, 'block', this.middlewareHelper.get());\n reactionsElement.render();\n reactionsElement.classList.add('no-stripe');\n reactionsElement.classList.remove('has-no-reactions');\n\n reactionsElement.append(this.btnClose);\n\n this.header.append(reactionsElement);\n\n const tabsContainer = document.createElement('div');\n tabsContainer.classList.add('tabs-container');\n tabsContainer.dataset.animation = 'tabs';\n\n const loaders: Map<HTMLElement, ScrollableLoader> = new Map();\n\n let hasAllReactions = false;\n if(newMessage.reactions.results.length) {\n const reaction = this.createFakeReaction('reactions', newMessage.reactions.results.reduce((acc, r) => acc + r.count, 0));\n\n reactionsElement.prepend(reaction);\n newMessage.reactions.results.unshift(reaction.reactionCount);\n hasAllReactions = true;\n }\n\n let hasReadParticipants = false;\n if(canViewReadParticipants) {\n try {\n const readUserIds = await this.managers.appMessagesManager.getMessageReadParticipants(message.peerId, message.mid);\n if(!middleware()) return;\n if(!readUserIds.length) {\n throw '';\n }\n\n const reaction = this.createFakeReaction('checks', readUserIds.length);\n\n reactionsElement.prepend(reaction);\n newMessage.reactions.results.unshift(reaction.reactionCount);\n hasReadParticipants = true;\n } catch(err) {\n\n }\n }\n\n newMessage.reactions.results.forEach((reactionCount) => {\n const scrollable = new Scrollable(undefined);\n scrollable.container.classList.add('tabs-tab');\n\n const section = new SettingSection({\n noShadow: true,\n noDelimiter: true\n });\n\n const chatlist = appDialogsManager.createChatList({\n dialogSize: 72\n });\n\n appDialogsManager.setListClickListener(chatlist, () => {\n this.hide();\n }, undefined, false, true);\n\n section.content.append(chatlist);\n scrollable.container.append(section.container);\n\n const skipReadParticipants = (reactionCount.reaction as any) !== 'checks';\n const skipReactionsList = (reactionCount.reaction as any) === 'checks';\n if(['checks', 'reactions'].includes(reactionCount.reaction as any)) {\n reactionCount.reaction = undefined;\n }\n\n const size = 24;\n const mediaSize = makeMediaSize(size, size);\n\n let nextOffset: string;\n const loader = new ScrollableLoader({\n scrollable,\n getPromise: async() => {\n const result = await this.managers.appMessagesManager.getMessageReactionsListAndReadParticipants(message, undefined, reactionCount.reaction, nextOffset, skipReadParticipants, skipReactionsList);\n nextOffset = result.nextOffset;\n\n await Promise.all(result.combined.map(async({peerId, reaction, date}) => {\n const {dom} = appDialogsManager.addDialogNew({\n peerId: peerId,\n autonomous: true,\n container: chatlist,\n avatarSize: 'abitbigger',\n rippleEnabled: false,\n meAsSaved: false\n });\n\n if(reaction) {\n const stickerContainer = document.createElement('div');\n stickerContainer.classList.add('reacted-list-reaction-icon');\n\n if(reaction._ === 'reactionEmoji') {\n const availableReaction = await this.managers.appReactionsManager.getReactionCached(reaction.emoticon);\n\n wrapSticker({\n doc: availableReaction.static_icon,\n div: stickerContainer,\n width: 24,\n height: 24,\n middleware\n });\n } else if(reaction._ === 'reactionCustomEmoji') {\n stickerContainer.append(wrapCustomEmoji({\n docIds: [reaction.document_id],\n customEmojiSize: mediaSize,\n middleware\n }));\n }\n\n dom.listEl.append(stickerContainer);\n }\n\n if(date && message.pFlags.out) {\n const c = document.createElement('span');\n dom.lastMessageSpan.style.cssText = `display: flex !important; align-items: center;`;\n const span = document.createElement('span');\n span.classList.add(reaction ? 'tgico-reactions' : 'tgico-checks', 'reacted-list-checks');\n const fragment = document.createDocumentFragment();\n c.append(formatFullSentTime(date, false));\n fragment.append(span, c);\n replaceContent(dom.lastMessageSpan, fragment);\n } else {\n const user = await this.managers.appUsersManager.getUser(peerId.toUserId());\n replaceContent(dom.lastMessageSpan, getUserStatusString(user));\n }\n }));\n\n return !nextOffset;\n }\n });\n\n loaders.set(scrollable.container, loader);\n\n tabsContainer.append(scrollable.container);\n });\n\n this.body.append(tabsContainer);\n\n const selectTab = horizontalMenu(reactionsElement, tabsContainer, (id, tabContent) => {\n if(id === (reactionsElement.childElementCount - 1)) {\n return false;\n }\n\n const reaction = reactionsElement.children[id] as ReactionElement;\n const prevId = selectTab.prevId();\n if(prevId !== -1) {\n (reactionsElement.children[prevId] as ReactionElement).setIsChosen(false);\n }\n\n reaction.setIsChosen(true);\n\n const loader = loaders.get(tabContent);\n loader.load();\n }, undefined, undefined, undefined, this.listenerSetter);\n\n // selectTab(hasAllReactions && hasReadParticipants ? 1 : 0, false);\n selectTab(0, false);\n\n this.show();\n }\n\n private createFakeReaction(icon: string, count: number) {\n const reaction = new ReactionElement();\n reaction.init('block', this.middlewareHelper.get());\n reaction.reactionCount = {\n _: 'reactionCount',\n count: count,\n reaction: icon as any\n };\n reaction.setCanRenderAvatars(false);\n reaction.renderCounter();\n\n const allReactionsSticker = document.createElement('div');\n allReactionsSticker.classList.add('reaction-counter', 'reaction-sticker-icon', 'tgico-' + icon);\n reaction.prepend(allReactionsSticker);\n\n return reaction;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport {IS_MOBILE, IS_SAFARI} from '../../environment/userAgent';\nimport assumeType from '../../helpers/assumeType';\nimport callbackify from '../../helpers/callbackify';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport getVisibleRect from '../../helpers/dom/getVisibleRect';\nimport liteMode from '../../helpers/liteMode';\nimport {getMiddleware} from '../../helpers/middleware';\nimport noop from '../../helpers/noop';\nimport {fastRaf} from '../../helpers/schedulers';\nimport {Message, AvailableReaction, Reaction} from '../../layer';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport lottieLoader from '../../lib/rlottie/lottieLoader';\nimport RLottiePlayer from '../../lib/rlottie/rlottiePlayer';\nimport rootScope from '../../lib/rootScope';\nimport animationIntersector, {AnimationItemGroup} from '../animationIntersector';\nimport Scrollable, {ScrollableBase, ScrollableX} from '../scrollable';\nimport wrapSticker from '../wrappers/sticker';\n\nconst REACTIONS_CLASS_NAME = 'btn-menu-reactions';\nconst REACTION_CLASS_NAME = REACTIONS_CLASS_NAME + '-reaction';\n\nconst REACTION_SIZE = 26;\nconst PADDING = 4;\nexport const REACTION_CONTAINER_SIZE = REACTION_SIZE + PADDING * 2;\n\nconst CAN_USE_TRANSFORM = !IS_SAFARI;\n\ntype ChatReactionsMenuPlayers = {\n select?: RLottiePlayer,\n appear?: RLottiePlayer,\n selectWrapper: HTMLElement,\n appearWrapper: HTMLElement,\n reaction: Reaction\n};\nexport class ChatReactionsMenu {\n public widthContainer: HTMLElement;\n public container: HTMLElement;\n private reactionsMap: Map<HTMLElement, ChatReactionsMenuPlayers>;\n public scrollable: ScrollableBase;\n private animationGroup: AnimationItemGroup;\n private middleware: ReturnType<typeof getMiddleware>;\n private message: Message.message;\n\n constructor(\n private managers: AppManagers,\n private type: 'horizontal' | 'vertical',\n middleware: ChatReactionsMenu['middleware']\n ) {\n const widthContainer = this.widthContainer = document.createElement('div');\n widthContainer.classList.add(REACTIONS_CLASS_NAME + '-container');\n widthContainer.classList.add(REACTIONS_CLASS_NAME + '-container-' + type);\n\n const reactionsContainer = this.container = document.createElement('div');\n reactionsContainer.classList.add(REACTIONS_CLASS_NAME);\n\n const reactionsScrollable = this.scrollable = type === 'vertical' ? new Scrollable(undefined) : new ScrollableX(undefined);\n reactionsContainer.append(reactionsScrollable.container);\n reactionsScrollable.onAdditionalScroll = this.onScroll;\n reactionsScrollable.setListeners();\n\n reactionsScrollable.container.classList.add('no-scrollbar');\n\n // ['big'].forEach((type) => {\n // const bubble = document.createElement('div');\n // bubble.classList.add(REACTIONS_CLASS_NAME + '-bubble', REACTIONS_CLASS_NAME + '-bubble-' + type);\n // reactionsContainer.append(bubble);\n // });\n\n this.reactionsMap = new Map();\n this.animationGroup = `CHAT-MENU-REACTIONS-${Date.now()}`;\n animationIntersector.setOverrideIdleGroup(this.animationGroup, true);\n\n if(!IS_TOUCH_SUPPORTED) {\n reactionsContainer.addEventListener('mousemove', this.onMouseMove);\n }\n\n attachClickEvent(reactionsContainer, (e) => {\n const reactionDiv = findUpClassName(e.target, REACTION_CLASS_NAME);\n if(!reactionDiv) return;\n\n const players = this.reactionsMap.get(reactionDiv);\n if(!players) return;\n\n this.managers.appReactionsManager.sendReaction(this.message, players.reaction);\n });\n\n widthContainer.append(reactionsContainer);\n\n this.middleware = middleware ?? getMiddleware();\n }\n\n public init(message: Message.message) {\n this.message = message;\n\n const middleware = this.middleware.get();\n // const result = Promise.resolve(this.appReactionsManager.getAvailableReactionsForPeer(message.peerId)).then((res) => pause(1000).then(() => res));\n const result = this.managers.appReactionsManager.getAvailableReactionsByMessage(message);\n callbackify(result, (reactions) => {\n if(!middleware() || !reactions.length) return;\n reactions.forEach((reaction) => {\n if(reaction.pFlags.premium && !rootScope.premium) return;\n this.renderReaction(reaction);\n });\n\n const setVisible = () => {\n this.container.classList.add('is-visible');\n };\n\n if(result instanceof Promise) {\n fastRaf(setVisible);\n } else {\n setVisible();\n }\n });\n }\n\n public cleanup() {\n this.middleware.clean();\n this.scrollable.removeListeners();\n this.reactionsMap.clear();\n animationIntersector.setOverrideIdleGroup(this.animationGroup, false);\n animationIntersector.checkAnimations(true, this.animationGroup, true);\n }\n\n private onScroll = () => {\n this.reactionsMap.forEach((players, div) => {\n this.onScrollProcessItem(div, players);\n });\n };\n\n private canUseAnimations() {\n return liteMode.isAvailable('animations') && liteMode.isAvailable('stickers_chat') && !IS_MOBILE;\n }\n\n private renderReaction(reaction: AvailableReaction) {\n const reactionDiv = document.createElement('div');\n reactionDiv.classList.add(REACTION_CLASS_NAME);\n\n const scaleContainer = document.createElement('div');\n scaleContainer.classList.add(REACTION_CLASS_NAME + '-scale');\n\n const appearWrapper = document.createElement('div');\n let selectWrapper: HTMLElement;;\n appearWrapper.classList.add(REACTION_CLASS_NAME + '-appear');\n\n if(this.canUseAnimations()) {\n selectWrapper = document.createElement('div');\n selectWrapper.classList.add(REACTION_CLASS_NAME + '-select', 'hide');\n }\n\n const players: ChatReactionsMenuPlayers = {\n selectWrapper,\n appearWrapper,\n reaction: {_: 'reactionEmoji', emoticon: reaction.reaction}\n };\n this.reactionsMap.set(reactionDiv, players);\n\n const middleware = this.middleware.get();\n\n const hoverScale = IS_TOUCH_SUPPORTED ? 1 : 1.25;\n const size = REACTION_SIZE * hoverScale;\n\n const options = {\n width: size,\n height: size,\n skipRatio: 1,\n needFadeIn: false,\n withThumb: false,\n group: this.animationGroup,\n middleware\n };\n\n if(!this.canUseAnimations()) {\n delete options.needFadeIn;\n delete options.withThumb;\n\n wrapSticker({\n doc: reaction.static_icon,\n div: appearWrapper,\n liteModeKey: false,\n ...options\n });\n } else {\n let isFirst = true;\n wrapSticker({\n doc: reaction.appear_animation,\n div: appearWrapper,\n play: true,\n liteModeKey: false,\n ...options\n }).then(({render}) => render).then((player) => {\n assumeType<RLottiePlayer>(player);\n\n players.appear = player;\n\n player.addEventListener('enterFrame', (frameNo) => {\n if(player.maxFrame === frameNo) {\n selectLoadPromise.then((selectPlayer) => {\n assumeType<RLottiePlayer>(selectPlayer);\n appearWrapper.classList.add('hide');\n selectWrapper.classList.remove('hide');\n\n if(isFirst) {\n players.select = selectPlayer;\n isFirst = false;\n }\n }, noop);\n }\n });\n }, noop);\n\n const selectLoadPromise = wrapSticker({\n doc: reaction.select_animation,\n div: selectWrapper,\n liteModeKey: false,\n ...options\n }).then(({render}) => render).then((player) => {\n assumeType<RLottiePlayer>(player);\n\n return lottieLoader.waitForFirstFrame(player);\n }).catch(noop);\n }\n\n scaleContainer.append(appearWrapper);\n selectWrapper && scaleContainer.append(selectWrapper);\n reactionDiv.append(scaleContainer);\n this.scrollable.append(reactionDiv);\n }\n\n private onScrollProcessItem(div: HTMLElement, players: ChatReactionsMenuPlayers) {\n // return;\n\n const scaleContainer = div.firstElementChild as HTMLElement;\n const visibleRect = getVisibleRect(div, this.scrollable.container);\n let transform: string;\n if(!visibleRect) {\n if(!players.appearWrapper.classList.contains('hide') || !players.appear) {\n return;\n }\n\n if(players.select) {\n players.select.stop();\n }\n\n players.appear.stop();\n players.appear.autoplay = true;\n players.appearWrapper.classList.remove('hide');\n players.selectWrapper.classList.add('hide');\n\n transform = '';\n } else if(visibleRect.overflow.left || visibleRect.overflow.right) {\n const diff = Math.abs(visibleRect.rect.left - visibleRect.rect.right);\n const scale = Math.min(diff ** 2 / REACTION_CONTAINER_SIZE ** 2, 1);\n\n transform = 'scale(' + scale + ')';\n } else {\n transform = '';\n }\n\n if(CAN_USE_TRANSFORM) {\n scaleContainer.style.transform = transform;\n }\n }\n\n private onMouseMove = (e: MouseEvent) => {\n const reactionDiv = findUpClassName(e.target, REACTION_CLASS_NAME);\n if(!reactionDiv) {\n return;\n }\n\n const players = this.reactionsMap.get(reactionDiv);\n if(!players) {\n return;\n }\n\n // do not play select animation when appearing\n if(!players.appear?.paused) {\n return;\n }\n\n const player = players.select;\n if(!player) {\n return;\n }\n\n if(player.paused) {\n player.autoplay = true;\n player.restart();\n }\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport type Chat from './chat';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport ButtonMenu, {ButtonMenuItemOptions} from '../buttonMenu';\nimport PopupDeleteMessages from '../popups/deleteMessages';\nimport PopupForward from '../popups/forward';\nimport PopupPinMessage from '../popups/unpinMessage';\nimport {copyTextToClipboard} from '../../helpers/clipboard';\nimport PopupSendNow from '../popups/sendNow';\nimport {toast} from '../toast';\nimport I18n, {i18n, LangPackKey} from '../../lib/langPack';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport {attachClickEvent, simulateClickEvent} from '../../helpers/dom/clickEvent';\nimport isSelectionEmpty from '../../helpers/dom/isSelectionEmpty';\nimport {Message, Poll, Chat as MTChat, MessageMedia, AvailableReaction, MessageEntity, InputStickerSet, StickerSet, Document, Reaction, Photo, SponsoredMessage} from '../../layer';\nimport PopupReportMessages from '../popups/reportMessages';\nimport assumeType from '../../helpers/assumeType';\nimport PopupSponsored from '../popups/sponsored';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport {getMiddleware} from '../../helpers/middleware';\nimport PeerTitle from '../peerTitle';\nimport StackedAvatars from '../stackedAvatars';\nimport {IS_APPLE} from '../../environment/userAgent';\nimport PopupReactedList from '../popups/reactedList';\nimport {ChatReactionsMenu, REACTION_CONTAINER_SIZE} from './reactionsMenu';\nimport getPeerId from '../../lib/appManagers/utils/peers/getPeerId';\nimport getServerMessageId from '../../lib/appManagers/utils/messageId/getServerMessageId';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport positionMenu, {MenuPositionPadding} from '../../helpers/positionMenu';\nimport contextMenuController from '../../helpers/contextMenuController';\nimport {attachContextMenuListener} from '../../helpers/dom/attachContextMenuListener';\nimport filterAsync from '../../helpers/array/filterAsync';\nimport appDownloadManager, {DownloadBlob} from '../../lib/appManagers/appDownloadManager';\nimport {SERVICE_PEER_ID} from '../../lib/mtproto/mtproto_config';\nimport {MessagesStorageKey, MyMessage} from '../../lib/appManagers/appMessagesManager';\nimport filterUnique from '../../helpers/array/filterUnique';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport deferredPromise, {CancellablePromise} from '../../helpers/cancellablePromise';\nimport PopupStickers from '../popups/stickers';\nimport getMediaFromMessage from '../../lib/appManagers/utils/messages/getMediaFromMessage';\nimport canSaveMessageMedia from '../../lib/appManagers/utils/messages/canSaveMessageMedia';\nimport getAlbumText from '../../lib/appManagers/utils/messages/getAlbumText';\nimport PopupElement from '../popups';\n\ntype ChatContextMenuButton = ButtonMenuItemOptions & {\n verify: () => boolean | Promise<boolean>,\n notDirect?: () => boolean,\n withSelection?: true,\n isSponsored?: true,\n localName?: 'views' | 'emojis' | 'sponsorInfo' | 'sponsorAdditionalInfo'\n};\n\nexport default class ChatContextMenu {\n private buttons: ChatContextMenuButton[];\n private element: HTMLElement;\n\n private isSelectable: boolean;\n private isSelected: boolean;\n private target: HTMLElement;\n private isTargetAGroupedItem: boolean;\n private isTextSelected: boolean;\n private isAnchorTarget: boolean;\n private isUsernameTarget: boolean;\n private isSponsored: boolean;\n private isOverBubble: boolean;\n private peerId: PeerId;\n private mid: number;\n private message: Message.message | Message.messageService;\n private sponsoredMessage: SponsoredMessage;\n private noForwards: boolean;\n\n private reactionsMenu: ChatReactionsMenu;\n private listenerSetter: ListenerSetter;\n private attachListenerSetter: ListenerSetter;\n\n private viewerPeerId: PeerId;\n private middleware: ReturnType<typeof getMiddleware>;\n private canOpenReactedList: boolean;\n\n private emojiInputsPromise: CancellablePromise<InputStickerSet.inputStickerSetID[]>;\n private albumMessages: Message.message[];\n private linkToMessage: Awaited<ReturnType<ChatContextMenu['getUrlToMessage']>>;\n private selectedMessagesText: string;\n private selectedMessages: MyMessage[];\n\n constructor(\n private chat: Chat,\n private managers: AppManagers\n ) {\n this.listenerSetter = new ListenerSetter();\n this.attachListenerSetter = new ListenerSetter();\n this.middleware = getMiddleware();\n }\n\n public attachTo(element: HTMLElement) {\n this.attachListenerSetter.removeAll();\n\n if(IS_TOUCH_SUPPORTED/* && false */) {\n attachClickEvent(element, (e) => {\n if(this.chat.selection.isSelecting) {\n return;\n }\n\n this.chat.log('touchend', e);\n\n const badSelectors = [\n '.name',\n '.peer-title',\n '.reply',\n '.document',\n 'audio-element',\n 'avatar-element',\n 'a',\n '.bubble-beside-button',\n 'replies-element',\n '[data-saved-from]:not(.bubble)',\n 'poll-element',\n '.attachment',\n '.reply-markup-button'\n ];\n const good = !(e.target as HTMLElement).closest(badSelectors.join(', '));\n if(good) {\n cancelEvent(e);\n // onContextMenu((e as TouchEvent).changedTouches[0]);\n // onContextMenu((e as TouchEvent).changedTouches ? (e as TouchEvent).changedTouches[0] : e as MouseEvent);\n this.onContextMenu(e);\n }\n }, {listenerSetter: this.attachListenerSetter});\n } else attachContextMenuListener({\n element,\n callback: this.onContextMenu,\n listenerSetter: this.attachListenerSetter\n });\n }\n\n private onContextMenu = (e: MouseEvent | Touch | TouchEvent) => {\n let bubble: HTMLElement, contentWrapper: HTMLElement;\n\n try {\n contentWrapper = findUpClassName(e.target, 'bubble-content-wrapper');\n bubble = contentWrapper ? contentWrapper.parentElement : findUpClassName(e.target, 'bubble');\n } catch(e) {}\n\n // ! context menu click by date bubble (there is no pointer-events)\n if(!bubble || bubble.classList.contains('bubble-first')) return;\n\n let element = this.element;\n if(e instanceof MouseEvent || e.hasOwnProperty('preventDefault')) (e as any).preventDefault();\n if(element && element.classList.contains('active')) {\n return false;\n }\n if(e instanceof MouseEvent || e.hasOwnProperty('cancelBubble')) (e as any).cancelBubble = true;\n\n let mid = +bubble.dataset.mid;\n if(!mid) return;\n\n const r = async() => {\n const isSponsored = this.isSponsored = mid < 0;\n this.isSelectable = this.chat.selection.canSelectBubble(bubble);\n this.peerId = this.chat.peerId;\n // this.msgID = msgID;\n this.target = e.target as HTMLElement;\n this.isTextSelected = !isSelectionEmpty();\n this.isAnchorTarget = this.target.tagName === 'A' && (\n (this.target as HTMLAnchorElement).target === '_blank' ||\n this.target.classList.contains('anchor-url')\n );\n this.isUsernameTarget = this.target.tagName === 'A' && this.target.classList.contains('mention');\n\n this.sponsoredMessage = isSponsored ? (bubble as any).message.sponsoredMessage : undefined;\n\n const mids = await this.chat.getMidsByMid(mid);\n // * если открыть контекстное меню для альбома не по бабблу, и последний элемент не выбран, чтобы показать остальные пункты\n if(this.chat.selection.isSelecting && !contentWrapper) {\n if(isSponsored) {\n return;\n }\n\n if(mids.length > 1) {\n const selectedMid = this.chat.selection.isMidSelected(this.peerId, mid) ?\n mid :\n mids.find((mid) => this.chat.selection.isMidSelected(this.peerId, mid));\n if(selectedMid) {\n mid = selectedMid;\n }\n }\n }\n\n this.isOverBubble = !!contentWrapper;\n\n const groupedItem = findUpClassName(this.target, 'grouped-item');\n this.isTargetAGroupedItem = !!groupedItem;\n if(groupedItem) {\n this.mid = +groupedItem.dataset.mid;\n } else {\n this.mid = mid;\n }\n\n this.isSelected = this.chat.selection.isMidSelected(this.peerId, this.mid);\n this.message = (bubble as any).message || await this.chat.getMessage(this.mid);\n this.albumMessages = (this.message as Message.message).grouped_id ? await this.managers.appMessagesManager.getMessagesByAlbum((this.message as Message.message).grouped_id) : undefined;\n this.noForwards = !isSponsored && !(await this.managers.appMessagesManager.canForward(this.message));\n this.viewerPeerId = undefined;\n this.canOpenReactedList = undefined;\n this.linkToMessage = await this.getUrlToMessage();\n this.selectedMessagesText = await this.getSelectedMessagesText();\n this.selectedMessages = this.chat.selection.isSelecting ? await this.chat.selection.getSelectedMessages() : undefined;\n\n const initResult = await this.init();\n if(!initResult) {\n return;\n }\n\n element = initResult.element;\n const {cleanup, destroy, menuPadding, reactionsMenu, reactionsMenuPosition} = initResult;\n let isReactionsMenuVisible = false;\n if(reactionsMenu) {\n const className = 'is-visible';\n isReactionsMenuVisible = reactionsMenu.container.classList.contains(className);\n if(isReactionsMenuVisible) reactionsMenu.container.classList.remove(className);\n\n if(reactionsMenuPosition === 'horizontal') {\n const offsetSize = element[/* reactionsMenuPosition === 'vertical' ? 'offsetHeight' : */'offsetWidth'];\n // if(reactionsMenu.scrollable.container.scrollWidth > offsetWidth) {\n const INNER_CONTAINER_PADDING = 8;\n const visibleLength = (offsetSize - INNER_CONTAINER_PADDING) / REACTION_CONTAINER_SIZE;\n const nextVisiblePart = visibleLength % 1;\n const MIN_NEXT_VISIBLE_PART = 0.65;\n if(nextVisiblePart < MIN_NEXT_VISIBLE_PART) {\n const minSize = (offsetSize + (MIN_NEXT_VISIBLE_PART - nextVisiblePart) * REACTION_CONTAINER_SIZE) | 0;\n element.style[/* reactionsMenuPosition === 'vertical' ? 'minHeight' : */'minWidth'] = minSize + 'px';\n }\n // }\n }\n }\n\n const side: 'left' | 'right' = bubble.classList.contains('is-in') ? 'left' : 'right';\n // bubble.parentElement.append(element);\n // appImManager.log('contextmenu', e, bubble, side);\n positionMenu((e as TouchEvent).touches ? (e as TouchEvent).touches[0] : e as MouseEvent, element, side, menuPadding);\n\n if(reactionsMenu) {\n reactionsMenu.widthContainer.style.top = element.style.top;\n reactionsMenu.widthContainer.style.left = element.style.left;\n reactionsMenu.widthContainer.style.setProperty('--menu-width', element[reactionsMenuPosition === 'vertical' ? 'offsetHeight' : 'offsetWidth'] + 'px');\n element.parentElement.append(reactionsMenu.widthContainer);\n if(isReactionsMenuVisible) void reactionsMenu.container.offsetLeft; // reflow\n }\n\n contextMenuController.openBtnMenu(element, () => {\n if(reactionsMenu) {\n reactionsMenu.container.classList.remove('is-visible');\n }\n\n this.mid = 0;\n this.peerId = undefined;\n this.target = null;\n this.viewerPeerId = undefined;\n this.canOpenReactedList = undefined;\n cleanup();\n\n setTimeout(() => {\n destroy();\n }, 300);\n });\n\n if(isReactionsMenuVisible) {\n reactionsMenu.container.classList.add('is-visible');\n }\n };\n\n r();\n };\n\n public cleanup() {\n this.listenerSetter.removeAll();\n this.reactionsMenu && this.reactionsMenu.cleanup();\n this.middleware.clean();\n }\n\n public destroy() {\n this.cleanup();\n this.attachListenerSetter.removeAll();\n }\n\n private async filterButtons(buttons: ChatContextMenu['buttons']) {\n return filterAsync(buttons, async(button) => {\n let good: boolean;\n\n if((this.isSponsored && !button.isSponsored) || (!this.isSponsored && button.isSponsored)) {\n return false;\n }\n\n // if((appImManager.chatSelection.isSelecting && !button.withSelection) || (button.withSelection && !appImManager.chatSelection.isSelecting)) {\n if(this.chat.selection.isSelecting && !button.withSelection) {\n good = false;\n } else {\n good = this.isOverBubble || IS_TOUCH_SUPPORTED || true ?\n await button.verify() :\n button.notDirect && await button.verify() && button.notDirect();\n }\n\n return !!good;\n });\n }\n\n private setButtons() {\n const verifyFavoriteSticker = async(toAdd: boolean) => {\n const doc = ((this.message as Message.message).media as MessageMedia.messageMediaDocument)?.document;\n if(!(doc as MyDocument)?.sticker) {\n return false;\n }\n\n const favedStickers = await this.managers.acknowledged.appStickersManager.getFavedStickersStickers();\n if(!favedStickers.cached) {\n return false;\n }\n\n const found = (await favedStickers.result).some((_doc) => _doc.id === doc.id);\n return toAdd ? !found : found;\n };\n\n this.buttons = [{\n icon: 'send2',\n text: 'MessageScheduleSend',\n onClick: this.onSendScheduledClick,\n verify: () => this.chat.type === 'scheduled' && !this.message.pFlags.is_outgoing\n }, {\n icon: 'send2',\n text: 'Message.Context.Selection.SendNow',\n onClick: this.onSendScheduledClick,\n verify: () => this.chat.type === 'scheduled' && this.isSelected && !this.chat.selection.selectionSendNowBtn.hasAttribute('disabled'),\n notDirect: () => true,\n withSelection: true\n }, {\n icon: 'schedule',\n text: 'MessageScheduleEditTime',\n onClick: () => {\n this.chat.input.scheduleSending(() => {\n assumeType<Message.message>(this.message);\n this.managers.appMessagesManager.editMessage(this.message, this.message.message, {\n scheduleDate: this.chat.input.scheduleDate,\n entities: this.message.entities\n });\n\n this.chat.input.onMessageSent(false, false);\n }, new Date(this.message.date * 1000));\n },\n verify: () => this.chat.type === 'scheduled'\n }, {\n icon: 'reply',\n text: 'Reply',\n onClick: this.onReplyClick,\n verify: async() => await this.chat.canSend() &&\n !this.message.pFlags.is_outgoing &&\n !!this.chat.input.messageInput &&\n this.chat.type !== 'scheduled'/* ,\n cancelEvent: true */\n }, {\n icon: 'favourites',\n text: 'AddToFavorites',\n onClick: this.onFaveStickerClick.bind(this, false),\n verify: () => verifyFavoriteSticker(true)\n }, {\n icon: 'favourites',\n text: 'DeleteFromFavorites',\n onClick: this.onFaveStickerClick.bind(this, true),\n verify: () => verifyFavoriteSticker(false)\n }, {\n icon: 'edit',\n text: 'Edit',\n onClick: this.onEditClick,\n verify: async() => (await this.managers.appMessagesManager.canEditMessage(this.message, 'text')) && !!this.chat.input.messageInput\n }, {\n icon: 'copy',\n text: 'Copy',\n onClick: this.onCopyClick,\n verify: () => !this.noForwards && !!(this.message as Message.message).message && !this.isTextSelected && (!this.isAnchorTarget || (this.message as Message.message).message !== this.target.innerText)\n }, {\n icon: 'copy',\n text: 'Chat.CopySelectedText',\n onClick: this.onCopyClick,\n verify: () => !this.noForwards && !!(this.message as Message.message).message && this.isTextSelected\n }, {\n icon: 'copy',\n text: 'Message.Context.Selection.Copy',\n onClick: this.onCopyClick,\n verify: async() => {\n if(!this.isSelected || this.noForwards) {\n return false;\n }\n\n for(const [peerId, mids] of this.chat.selection.selectedMids) {\n const storageKey: MessagesStorageKey = `${peerId}_${this.chat.type === 'scheduled' ? 'scheduled' : 'history'}`;\n for(const mid of mids) {\n const message = (await this.managers.appMessagesManager.getMessageFromStorage(storageKey, mid)) as Message.message;\n if(!!message.message) {\n return true;\n }\n }\n }\n\n return false;\n },\n notDirect: () => true,\n withSelection: true\n }, {\n icon: 'copy',\n text: 'CopyLink',\n onClick: this.onCopyAnchorLinkClick,\n verify: () => this.isAnchorTarget,\n withSelection: true\n }, {\n icon: 'copy',\n text: 'Text.Context.Copy.Username',\n onClick: () => {\n copyTextToClipboard(this.target.textContent);\n },\n verify: () => this.isUsernameTarget,\n withSelection: true\n }, {\n icon: 'copy',\n text: 'Text.Context.Copy.Hashtag',\n onClick: () => {\n copyTextToClipboard(this.target.textContent);\n },\n verify: () => this.target.classList.contains('anchor-hashtag'),\n withSelection: true\n }, {\n icon: 'link',\n text: 'MessageContext.CopyMessageLink1',\n onClick: this.onCopyLinkClick,\n verify: async() => await this.managers.appPeersManager.isChannel(this.peerId) && !this.message.pFlags.is_outgoing\n }, {\n icon: 'pin',\n text: 'Message.Context.Pin',\n onClick: this.onPinClick,\n verify: async() => !this.message.pFlags.is_outgoing &&\n this.message._ !== 'messageService' &&\n !this.message.pFlags.pinned &&\n await this.managers.appPeersManager.canPinMessage(this.peerId) &&\n this.chat.type !== 'scheduled'\n }, {\n icon: 'unpin',\n text: 'Message.Context.Unpin',\n onClick: this.onUnpinClick,\n verify: async() => (this.message as Message.message).pFlags.pinned && await this.managers.appPeersManager.canPinMessage(this.peerId)\n }, {\n icon: 'download',\n text: 'MediaViewer.Context.Download',\n onClick: () => ChatContextMenu.onDownloadClick(this.message, this.noForwards),\n verify: () => ChatContextMenu.canDownload(this.message, this.target, this.noForwards)\n }, {\n icon: 'checkretract',\n text: 'Chat.Poll.Unvote',\n onClick: this.onRetractVote,\n verify: () => {\n const poll = (this.message as any).media?.poll as Poll;\n return poll && poll.chosenIndexes.length && !poll.pFlags.closed && !poll.pFlags.quiz;\n }/* ,\n cancelEvent: true */\n }, {\n icon: 'stop',\n text: 'Chat.Poll.Stop',\n onClick: this.onStopPoll,\n verify: async() => {\n const poll = (this.message as any).media?.poll;\n return await this.managers.appMessagesManager.canEditMessage(this.message, 'poll') && poll && !poll.pFlags.closed && !this.message.pFlags.is_outgoing;\n }/* ,\n cancelEvent: true */\n }, {\n icon: 'forward',\n text: 'Forward',\n onClick: this.onForwardClick, // let forward the message if it's outgoing but not ours (like a changelog)\n verify: () => !this.noForwards && this.chat.type !== 'scheduled' && (!this.message.pFlags.is_outgoing || this.message.fromId === SERVICE_PEER_ID) && this.message._ !== 'messageService'\n }, {\n icon: 'forward',\n text: 'Message.Context.Selection.Forward',\n onClick: this.onForwardClick,\n verify: () => this.chat.selection.selectionForwardBtn &&\n this.isSelected &&\n !this.chat.selection.selectionForwardBtn.hasAttribute('disabled'),\n notDirect: () => true,\n withSelection: true\n }, {\n icon: 'download',\n text: 'Message.Context.Selection.Download',\n onClick: () => ChatContextMenu.onDownloadClick(this.selectedMessages, this.noForwards),\n verify: () => this.selectedMessages && ChatContextMenu.canDownload(this.selectedMessages, undefined, this.noForwards),\n withSelection: true\n }, {\n icon: 'flag',\n text: 'ReportChat',\n onClick: () => {\n PopupElement.createPopup(PopupReportMessages, this.peerId, [this.mid]);\n },\n verify: async() => !this.message.pFlags.out && this.message._ === 'message' && !this.message.pFlags.is_outgoing && await this.managers.appPeersManager.isChannel(this.peerId),\n notDirect: () => true,\n withSelection: true\n }, {\n icon: 'select',\n text: 'Message.Context.Select',\n onClick: this.onSelectClick,\n verify: () => !(this.message as Message.messageService).action && !this.isSelected && this.isSelectable,\n notDirect: () => true,\n withSelection: true\n }, {\n icon: 'select',\n text: 'Message.Context.Selection.Clear',\n onClick: this.onClearSelectionClick,\n verify: () => this.isSelected,\n notDirect: () => true,\n withSelection: true\n }, {\n onClick: () => {\n if(this.viewerPeerId && false) {\n this.chat.appImManager.setInnerPeer({\n peerId: this.viewerPeerId\n });\n } else if(this.canOpenReactedList) {\n PopupElement.createPopup(PopupReactedList, this.message as Message.message);\n } else {\n return false;\n }\n },\n verify: async() => !this.peerId.isUser() && (!!(this.message as Message.message).reactions?.recent_reactions?.length || await this.managers.appMessagesManager.canViewMessageReadParticipants(this.message)),\n notDirect: () => true,\n localName: 'views'\n }, {\n icon: 'delete danger',\n text: 'Delete',\n onClick: this.onDeleteClick,\n verify: async() => this.managers.appMessagesManager.canDeleteMessage(this.message)\n }, {\n icon: 'delete danger',\n text: 'Message.Context.Selection.Delete',\n onClick: this.onDeleteClick,\n verify: () => this.isSelected && !this.chat.selection.selectionDeleteBtn.hasAttribute('disabled'),\n notDirect: () => true,\n withSelection: true\n }, {\n icon: 'info',\n text: 'Chat.Message.Sponsored.What',\n onClick: () => {\n PopupElement.createPopup(PopupSponsored);\n },\n verify: () => this.isSponsored,\n isSponsored: true\n }, {\n icon: 'copy',\n text: 'Copy',\n onClick: () => copyTextToClipboard(this.sponsoredMessage.message),\n verify: () => this.isSponsored,\n isSponsored: true\n }, {\n // icon: 'smile',\n text: 'Loading',\n onClick: () => {\n this.emojiInputsPromise.then((inputs) => {\n PopupElement.createPopup(PopupStickers, inputs, true).show();\n });\n },\n verify: () => !!this.getUniqueCustomEmojisFromMessage().length,\n notDirect: () => true,\n localName: 'emojis'\n }, {\n regularText: this.sponsoredMessage?.sponsor_info ? wrapEmojiText(this.sponsoredMessage.sponsor_info) : undefined,\n separator: true,\n multiline: true,\n onClick: () => copyTextToClipboard(this.sponsoredMessage.sponsor_info),\n verify: () => !!this.sponsoredMessage.sponsor_info,\n isSponsored: true\n }, {\n regularText: this.sponsoredMessage?.additional_info ? wrapEmojiText(this.sponsoredMessage.additional_info) : undefined,\n separator: true,\n multiline: true,\n onClick: () => copyTextToClipboard(this.sponsoredMessage.additional_info),\n verify: () => !!this.sponsoredMessage.additional_info,\n isSponsored: true\n }];\n }\n\n public static canDownload(message: MyMessage | MyMessage[], withTarget?: HTMLElement, noForwards?: boolean): boolean {\n if(Array.isArray(message)) {\n return message.some((message) => ChatContextMenu.canDownload(message, withTarget, noForwards));\n }\n\n if(!canSaveMessageMedia(message) || noForwards) {\n return false;\n }\n\n const isPhoto: boolean = !!((message as Message.message).media as MessageMedia.messageMediaPhoto)?.photo;\n let isGoodType = false\n\n if(isPhoto) {\n isGoodType = true;\n } else {\n const doc: MyDocument = ((message as Message.message).media as MessageMedia.messageMediaDocument)?.document as any;\n if(!doc) return false;\n // isGoodType = doc.type && (['gif', 'video', 'audio', 'voice', 'sticker'] as MyDocument['type'][]).includes(doc.type)\n isGoodType = true;\n }\n\n let hasTarget = !withTarget || !!IS_TOUCH_SUPPORTED;\n\n if(isGoodType && withTarget) {\n hasTarget ||= !!(findUpClassName(withTarget, 'document') ||\n findUpClassName(withTarget, 'audio') ||\n findUpClassName(withTarget, 'media-sticker-wrapper') ||\n findUpClassName(withTarget, 'media-photo') ||\n findUpClassName(withTarget, 'media-video'));\n }\n\n return isGoodType && hasTarget;\n }\n\n private getMessageWithText() {\n return (this.albumMessages && getAlbumText(this.albumMessages)) || this.message;\n }\n\n private getUniqueCustomEmojisFromMessage() {\n const docIds: DocId[] = [];\n\n const message = this.getMessageWithText();\n\n const entities = (message as Message.message).entities;\n if(entities) {\n const filtered = entities.filter((entity) => entity._ === 'messageEntityCustomEmoji') as MessageEntity.messageEntityCustomEmoji[];\n docIds.push(...filtered.map((entity) => entity.document_id));\n }\n\n const reactions = (message as Message.message).reactions;\n if(reactions) {\n const results = reactions.results.filter((reactionCount) => reactionCount.reaction._ === 'reactionCustomEmoji');\n docIds.push(...results.map((reactionCount) => (reactionCount.reaction as Reaction.reactionCustomEmoji).document_id));\n }\n\n return filterUnique(docIds);\n }\n\n private async init() {\n this.cleanup();\n this.setButtons();\n\n const filteredButtons = await this.filterButtons(this.buttons);\n if(!filteredButtons.length) {\n return;\n }\n\n const element = this.element = await ButtonMenu({\n buttons: filteredButtons,\n listenerSetter: this.listenerSetter\n });\n element.id = 'bubble-contextmenu';\n element.classList.add('contextmenu');\n\n const viewsButton = filteredButtons.find((button) => button.localName === 'views');\n if(viewsButton) {\n const reactions = (this.message as Message.message).reactions;\n const recentReactions = reactions?.recent_reactions;\n const isViewingReactions = !!recentReactions?.length;\n const participantsCount = await this.managers.appMessagesManager.canViewMessageReadParticipants(this.message) ?\n ((await this.managers.appPeersManager.getPeer(this.peerId)) as MTChat.chat).participants_count :\n undefined;\n const reactedLength = reactions ? reactions.results.reduce((acc, r) => acc + r.count, 0) : undefined;\n\n viewsButton.element.classList.add('tgico-' + (isViewingReactions ? 'reactions' : 'checks'));\n const i18nElem = new I18n.IntlElement({\n key: isViewingReactions ? (\n participantsCount === undefined ? 'Chat.Context.ReactedFast' : 'Chat.Context.Reacted'\n ) : 'NobodyViewed',\n args: isViewingReactions ? (\n participantsCount === undefined ? [reactedLength] : [participantsCount, participantsCount]\n ) : undefined,\n element: viewsButton.textElement\n });\n\n let fakeText: HTMLElement;\n if(isViewingReactions) {\n if(participantsCount === undefined) {\n fakeText = i18n('Chat.Context.ReactedFast', [reactedLength]);\n } else {\n fakeText = i18n(\n recentReactions.length === participantsCount ? 'Chat.Context.ReactedFast' : 'Chat.Context.Reacted',\n [recentReactions.length, participantsCount]\n );\n }\n } else {\n fakeText = i18n('Loading');\n }\n\n fakeText.classList.add('btn-menu-item-text-fake');\n viewsButton.element.append(fakeText);\n\n const AVATAR_SIZE = 22;\n const MAX_AVATARS = 3;\n const PADDING_PER_AVATAR = 1.125;\n i18nElem.element.style.visibility = 'hidden';\n i18nElem.element.style.paddingRight = isViewingReactions ? PADDING_PER_AVATAR * Math.min(MAX_AVATARS, recentReactions.length) + 'rem' : '1rem';\n const middleware = this.middleware.get();\n this.managers.appMessagesManager.getMessageReactionsListAndReadParticipants(this.message as Message.message).then((result) => {\n if(!middleware()) {\n return;\n }\n\n fakeText?.remove();\n\n const reactions = result.combined;\n const reactedLength = participantsCount === undefined ?\n result.reactionsCount :\n (\n isViewingReactions ?\n reactions.filter((reaction) => reaction.reaction).length :\n reactions.length\n );\n\n let fakeElem: HTMLElement;\n if(reactions.length === 1) {\n fakeElem = new PeerTitle({\n peerId: reactions[0].peerId,\n onlyFirstName: true,\n dialog: false\n }).element;\n\n if(!isViewingReactions || result.readParticipantDates.length <= 1) {\n this.viewerPeerId = reactions[0].peerId;\n }\n } else if(isViewingReactions) {\n const isFull = reactedLength === reactions.length || participantsCount === undefined;\n fakeElem = i18n(\n isFull ? 'Chat.Context.ReactedFast' : 'Chat.Context.Reacted',\n isFull ? [reactedLength] : [reactedLength, reactions.length]\n );\n } else {\n if(!reactions.length) {\n i18nElem.element.style.visibility = '';\n } else {\n fakeElem = i18n('MessageSeen', [reactions.length]);\n }\n }\n\n if(fakeElem) {\n fakeElem.style.paddingRight = PADDING_PER_AVATAR * Math.min(MAX_AVATARS, reactedLength) + 'rem';\n fakeElem.classList.add('btn-menu-item-text-fake');\n viewsButton.element.append(fakeElem);\n }\n\n if(reactions.length) {\n const avatars = new StackedAvatars({avatarSize: AVATAR_SIZE});\n avatars.render(recentReactions ? recentReactions.map((r) => getPeerId(r.peer_id)) : reactions.map((reaction) => reaction.peerId));\n viewsButton.element.append(avatars.container);\n\n // if(reactions.length > 1) {\n // if(isViewingReactions) {\n this.canOpenReactedList = true;\n // }\n }\n });\n }\n\n let menuPadding: MenuPositionPadding;\n let reactionsMenu: ChatReactionsMenu;\n let reactionsMenuPosition: 'horizontal' | 'vertical';\n if(\n this.message._ === 'message' &&\n !this.chat.selection.isSelecting &&\n !this.message.pFlags.is_outgoing &&\n !this.message.pFlags.is_scheduled &&\n !this.message.pFlags.local\n ) {\n reactionsMenuPosition = (IS_APPLE || IS_TOUCH_SUPPORTED)/* && false */ ? 'horizontal' : 'vertical';\n reactionsMenu = this.reactionsMenu = new ChatReactionsMenu(this.managers, reactionsMenuPosition, this.middleware);\n reactionsMenu.init(await this.managers.appMessagesManager.getGroupsFirstMessage(this.message));\n // element.prepend(reactionsMenu.widthContainer);\n\n const size = 36;\n const margin = 8;\n const totalSize = size + margin;\n const paddingLeft = 0, paddingRight = 0;\n if(reactionsMenuPosition === 'vertical') {\n menuPadding = {\n top: paddingLeft,\n // bottom: 36, // positionMenu will detect it itself somehow\n left: totalSize\n };\n } else {\n menuPadding = {\n top: totalSize,\n right: paddingRight,\n left: paddingLeft\n };\n }\n }\n\n const emojisButton = filteredButtons.find((button) => button.localName === 'emojis');\n if(emojisButton) {\n emojisButton.element.classList.add('is-multiline');\n emojisButton.element.parentElement.insertBefore(document.createElement('hr'), emojisButton.element);\n\n const setPadding = () => {\n menuPadding ??= {};\n menuPadding.bottom = 24;\n };\n\n const docIds = this.getUniqueCustomEmojisFromMessage();\n const inputsPromise = this.emojiInputsPromise = deferredPromise();\n\n await this.managers.appEmojiManager.getCachedCustomEmojiDocuments(docIds).then(async(docs) => {\n const p = async(docs: Document.document[]) => {\n const s: Map<StickerSet['id'], InputStickerSet.inputStickerSetID> = new Map();\n docs.forEach((doc) => {\n if(!doc || s.has(doc.stickerSetInput.id)) {\n return;\n }\n\n s.set(doc.stickerSetInput.id, doc.stickerSetInput);\n });\n\n const inputs = [...s.values()];\n inputsPromise.resolve(inputs);\n if(s.size === 1) {\n const result = await this.managers.acknowledged.appStickersManager.getStickerSet(inputs[0]);\n const promise = result.result.then((set) => {\n const el = i18n('MessageContainsEmojiPack', [wrapEmojiText(set.set.title)]);\n replaceContent(emojisButton.textElement, el);\n });\n\n return result.cached ? promise : (setPadding(), undefined);\n }\n\n replaceContent(emojisButton.textElement, i18n('MessageContainsEmojiPacks', [s.size]));\n };\n\n if(docs.some((doc) => !doc)) {\n setPadding();\n this.managers.appEmojiManager.getCustomEmojiDocuments(docIds).then(p);\n } else {\n return p(docs);\n }\n });\n // emojisButton.element.append(i18n('Loading'));\n }\n\n this.chat.container.append(element);\n\n return {\n element,\n cleanup: () => {\n this.cleanup();\n reactionsMenu && reactionsMenu.cleanup();\n },\n destroy: () => {\n element.remove();\n reactionsMenu && reactionsMenu.widthContainer.remove();\n },\n menuPadding,\n reactionsMenu,\n reactionsMenuPosition\n };\n }\n\n private async getUrlToMessage() {\n if(this.peerId.isUser()) {\n return;\n }\n\n let threadMessage: Message.message;\n const {peerId, mid} = this;\n const threadId = this.chat.threadId;\n if(this.chat.type === 'discussion') {\n threadMessage = (await this.managers.appMessagesManager.getMessageByPeer(peerId, threadId)) as Message.message;\n }\n\n const username = await this.managers.appPeersManager.getPeerUsername(threadMessage ? threadMessage.fromId : peerId);\n const msgId = getServerMessageId(mid);\n let url = 'https://t.me/';\n if(username) {\n url += username;\n if(threadMessage) url += `/${getServerMessageId(threadMessage.fwd_from.channel_post)}?comment=${msgId}`;\n else if(threadId) url += `/${getServerMessageId(threadId)}/${msgId}`;\n else url += '/' + msgId;\n } else {\n url += 'c/' + peerId.toChatId();\n if(threadMessage) url += `/${msgId}?thread=${getServerMessageId(threadMessage.mid)}`;\n else if(threadId) url += `/${getServerMessageId(threadId)}/${msgId}`;\n else url += '/' + msgId;\n }\n\n return {url, isPrivate: !username};\n }\n\n private async getSelectedMessagesText() {\n if(!isSelectionEmpty()) {\n return '';\n }\n\n const mids = this.chat.selection.isSelecting ?\n [...this.chat.selection.selectedMids.get(this.peerId)].sort((a, b) => a - b) :\n [this.mid];\n\n const parts: string[] = await Promise.all(mids.map(async(mid) => {\n const message = (await this.chat.getMessage(mid)) as Message.message;\n return message?.message ? message.message + '\\n' : '';\n }));\n\n return parts.join('');\n }\n\n private onSendScheduledClick = async() => {\n if(this.chat.selection.isSelecting) {\n simulateClickEvent(this.chat.selection.selectionSendNowBtn);\n } else {\n PopupElement.createPopup(PopupSendNow, this.peerId, await this.chat.getMidsByMid(this.mid));\n }\n };\n\n private onReplyClick = () => {\n this.chat.input.initMessageReply(this.mid);\n };\n\n private onFaveStickerClick = (unfave?: boolean) => {\n const docId = ((this.message as Message.message).media as MessageMedia.messageMediaDocument).document.id;\n this.managers.appStickersManager.faveSticker(docId, unfave);\n };\n\n private onEditClick = () => {\n const message = this.getMessageWithText();\n this.chat.input.initMessageEditing(this.isTargetAGroupedItem ? this.mid : message.mid);\n };\n\n private onCopyClick = async() => {\n if(isSelectionEmpty()) {\n copyTextToClipboard(this.selectedMessagesText);\n } else {\n document.execCommand('copy');\n // cancelSelection();\n }\n };\n\n private onCopyAnchorLinkClick = () => {\n copyTextToClipboard((this.target as HTMLAnchorElement).href);\n };\n\n private onCopyLinkClick = () => {\n const {url, isPrivate} = this.linkToMessage;\n const key: LangPackKey = isPrivate ? 'LinkCopiedPrivateInfo' : 'LinkCopied';\n toast(I18n.format(key, true));\n copyTextToClipboard(url);\n };\n\n private onPinClick = () => {\n PopupElement.createPopup(PopupPinMessage, this.peerId, this.mid);\n };\n\n private onUnpinClick = () => {\n PopupElement.createPopup(PopupPinMessage, this.peerId, this.mid, true);\n };\n\n private onRetractVote = () => {\n this.managers.appPollsManager.sendVote(this.message as Message.message, []);\n };\n\n private onStopPoll = () => {\n this.managers.appPollsManager.stopPoll(this.message as Message.message);\n };\n\n private onForwardClick = async() => {\n if(this.chat.selection.isSelecting) {\n simulateClickEvent(this.chat.selection.selectionForwardBtn);\n } else {\n const peerId = this.peerId;\n const mids = this.isTargetAGroupedItem ? [this.mid] : await this.chat.getMidsByMid(this.mid);\n PopupForward.create({\n [peerId]: mids\n });\n }\n };\n\n private onSelectClick = () => {\n this.chat.selection.toggleByElement(findUpClassName(this.target, 'grouped-item') || findUpClassName(this.target, 'bubble'));\n };\n\n private onClearSelectionClick = () => {\n this.chat.selection.cancelSelection();\n };\n\n private onDeleteClick = async() => {\n if(this.chat.selection.isSelecting) {\n simulateClickEvent(this.chat.selection.selectionDeleteBtn);\n } else {\n PopupElement.createPopup(PopupDeleteMessages, this.peerId, this.isTargetAGroupedItem ? [this.mid] : await this.chat.getMidsByMid(this.mid), this.chat.type);\n }\n };\n\n public static onDownloadClick(messages: MyMessage | MyMessage[], noForwards?: boolean): DownloadBlob | DownloadBlob[] {\n if(Array.isArray(messages)) {\n return messages.map((message) => {\n return this.onDownloadClick(message) as any;\n });\n }\n\n if(!this.canDownload(messages, undefined, noForwards)) {\n return;\n }\n\n return appDownloadManager.downloadToDisc({media: getMediaFromMessage(messages, true)});\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko, Artem Kolnogorov and unknown creator of the script taken from http://useless.altervista.org/gradient.html\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {animateSingle} from '../../helpers/animation';\nimport {hexToRgb} from '../../helpers/color';\nimport {easeOutQuadApply} from '../../helpers/easing/easeOutQuad';\n\nconst WIDTH = 50;\nconst HEIGHT = WIDTH;\n\nexport default class ChatBackgroundGradientRenderer {\n private readonly _width = WIDTH;\n private readonly _height = HEIGHT;\n private _phase: number;\n private _tail: number;\n private readonly _tails = 90;\n private readonly _scrollTails = 50;\n private _frames: ImageData[];\n private _colors: {r: number, g: number, b: number}[];\n private readonly _curve = [\n 0, 0.25, 0.50, 0.75, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12,\n 13, 14, 15, 16, 17, 18, 18.3, 18.6, 18.9, 19.2, 19.5, 19.8, 20.1, 20.4, 20.7,\n 21.0, 21.3, 21.6, 21.9, 22.2, 22.5, 22.8, 23.1, 23.4, 23.7, 24.0, 24.3, 24.6,\n 24.9, 25.2, 25.5, 25.8, 26.1, 26.3, 26.4, 26.5, 26.6, 26.7, 26.8, 26.9, 27\n ];\n private readonly _incrementalCurve: number[];\n private readonly _positions = [\n {x: 0.80, y: 0.10},\n {x: 0.60, y: 0.20},\n {x: 0.35, y: 0.25},\n {x: 0.25, y: 0.60},\n {x: 0.20, y: 0.90},\n {x: 0.40, y: 0.80},\n {x: 0.65, y: 0.75},\n {x: 0.75, y: 0.40}\n ];\n private readonly _phases = this._positions.length;\n private _onWheelRAF: number;\n private _scrollDelta: number;\n\n // private _ts = 0;\n // private _fps = 15;\n // private _frametime = 1000 / this._fps;\n // private _raf: number;\n\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _hc: HTMLCanvasElement;\n private _hctx: CanvasRenderingContext2D;\n\n private _addedScrollListener: boolean;\n private _animatingToNextPosition: boolean;\n private _nextPositionTail: number;\n private _nextPositionTails: number;\n private _nextPositionLeft: number;\n\n constructor() {\n const diff = this._tails / this._curve[this._curve.length - 1];\n\n for(let i = 0, length = this._curve.length; i < length; ++i) {\n this._curve[i] = this._curve[i] * diff;\n }\n\n this._incrementalCurve = this._curve.map((v, i, arr) => {\n return v - (arr[i - 1] ?? 0);\n });\n }\n\n private hexToRgb(hex: string) {\n const result = hexToRgb(hex);\n return {r: result[0], g: result[1], b: result[2]};\n }\n\n private getPositions(shift: number) {\n const positions = this._positions.slice();\n positions.push(...positions.splice(0, shift));\n\n const result: typeof positions = [];\n for(let i = 0; i < positions.length; i += 2) {\n result.push(positions[i]);\n }\n return result;\n }\n\n private getNextPositions(phase: number, curveMax: number, curve: number[]) {\n const pos = this.getPositions(phase);\n if(!curve[0] && curve.length === 1) {\n return [pos];\n }\n\n const nextPos = this.getPositions(++phase % this._phases);\n const distances = nextPos.map((nextPos, idx) => {\n return {\n x: (nextPos.x - pos[idx].x) / curveMax,\n y: (nextPos.y - pos[idx].y) / curveMax\n };\n });\n\n const positions = curve.map((value) => {\n return distances.map((distance, idx) => {\n return {\n x: pos[idx].x + distance.x * value,\n y: pos[idx].y + distance.y * value\n };\n });\n });\n\n return positions;\n }\n\n private curPosition(phase: number, tail: number) {\n const positions = this.getNextPositions(phase, this._tails, [tail]);\n return positions[0];\n }\n\n private changeTail(diff: number) {\n this._tail += diff;\n\n while(this._tail >= this._tails) {\n this._tail -= this._tails;\n if(++this._phase >= this._phases) {\n this._phase -= this._phases;\n }\n }\n\n while(this._tail < 0) {\n this._tail += this._tails;\n if(--this._phase < 0) {\n this._phase += this._phases;\n }\n }\n }\n\n private onWheel = (e: {deltaY: number}) => {\n if(this._animatingToNextPosition) {\n return;\n }\n\n this._scrollDelta += e.deltaY;\n if(this._onWheelRAF === undefined) {\n this._onWheelRAF = requestAnimationFrame(this.drawOnWheel);\n }\n };\n\n private changeTailAndDraw(diff: number) {\n this.changeTail(diff);\n const curPos = this.curPosition(this._phase, this._tail);\n this.drawGradient(curPos);\n }\n\n private drawOnWheel = () => {\n const value = this._scrollDelta / this._scrollTails;\n this._scrollDelta %= this._scrollTails;\n const diff = value > 0 ? Math.floor(value) : Math.ceil(value);\n if(diff) {\n this.changeTailAndDraw(diff);\n }\n this._onWheelRAF = undefined;\n };\n\n private drawNextPositionAnimated = (getProgress?: () => number) => {\n let done: boolean, id: ImageData;\n if(getProgress) {\n const value = getProgress();\n done = value >= 1;\n const transitionValue = easeOutQuadApply(value, 1);\n const nextPositionTail = this._nextPositionTail ?? 0;\n const tail = this._nextPositionTail = this._nextPositionTails * transitionValue;\n const diff = tail - nextPositionTail;\n if(diff) {\n this._nextPositionLeft -= diff;\n this.changeTailAndDraw(diff);\n }\n } else {\n const frames = this._frames;\n id = frames.shift();\n done = !frames.length;\n }\n\n if(id) {\n this.drawImageData(id);\n }\n\n if(done) {\n this._nextPositionLeft = undefined;\n this._nextPositionTails = undefined;\n this._nextPositionTail = undefined;\n this._animatingToNextPosition = undefined;\n }\n\n return !done;\n };\n\n private getGradientImageData(positions: {x: number, y: number}[]) {\n const id = this._hctx.createImageData(this._width, this._height);\n const pixels = id.data;\n\n let offset = 0;\n for(let y = 0; y < this._height; ++y) {\n const directPixelY = y / this._height;\n const centerDistanceY = directPixelY - 0.5;\n const centerDistanceY2 = centerDistanceY * centerDistanceY;\n\n for(let x = 0; x < this._width; ++x) {\n const directPixelX = x / this._width;\n\n const centerDistanceX = directPixelX - 0.5;\n const centerDistance = Math.sqrt(centerDistanceX * centerDistanceX + centerDistanceY2);\n\n const swirlFactor = 0.35 * centerDistance;\n const theta = swirlFactor * swirlFactor * 0.8 * 8.0;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n const pixelX = Math.max(0.0, Math.min(1.0, 0.5 + centerDistanceX * cosTheta - centerDistanceY * sinTheta));\n const pixelY = Math.max(0.0, Math.min(1.0, 0.5 + centerDistanceX * sinTheta + centerDistanceY * cosTheta));\n\n let distanceSum = 0.0;\n\n let r = 0.0;\n let g = 0.0;\n let b = 0.0;\n\n for(let i = 0; i < this._colors.length; i++) {\n const colorX = positions[i].x;\n const colorY = positions[i].y;\n\n const distanceX = pixelX - colorX;\n const distanceY = pixelY - colorY;\n\n let distance = Math.max(0.0, 0.9 - Math.sqrt(distanceX * distanceX + distanceY * distanceY));\n distance = distance * distance * distance * distance;\n distanceSum += distance;\n\n r += distance * this._colors[i].r / 255;\n g += distance * this._colors[i].g / 255;\n b += distance * this._colors[i].b / 255;\n }\n\n pixels[offset++] = r / distanceSum * 255.0;\n pixels[offset++] = g / distanceSum * 255.0;\n pixels[offset++] = b / distanceSum * 255.0;\n pixels[offset++] = 0xFF;\n }\n }\n return id;\n }\n\n private drawImageData(id: ImageData) {\n this._hctx.putImageData(id, 0, 0);\n this._ctx.drawImage(this._hc, 0, 0, this._width, this._height);\n }\n\n private drawGradient(positions: {x: number, y: number}[]) {\n this.drawImageData(this.getGradientImageData(positions));\n }\n\n // private doAnimate = () => {\n // const now = +Date.now();\n // if(!document.hasFocus() || (now - this._ts) < this._frametime) {\n // this._raf = requestAnimationFrame(this.doAnimate);\n // return;\n // }\n\n // this._ts = now;\n // this.changeTail(1);\n // const cur_pos = this.curPosition(this._phase, this._tail);\n // this.drawGradient(cur_pos);\n // this._raf = requestAnimationFrame(this.doAnimate);\n // };\n\n // public animate(start?: boolean) {\n // if(!start) {\n // cancelAnimationFrame(this._raf);\n // return;\n // }\n // this.doAnimate();\n // }\n\n public init(el: HTMLCanvasElement) {\n this._frames = [];\n this._phase = 0;\n this._tail = 0;\n this._scrollDelta = 0;\n if(this._onWheelRAF !== undefined) {\n cancelAnimationFrame(this._onWheelRAF);\n this._onWheelRAF = undefined;\n }\n\n const colors = el.getAttribute('data-colors').split(',').reverse();\n this._colors = colors.map((color) => {\n return this.hexToRgb(color);\n });\n\n if(!this._hc) {\n this._hc = document.createElement('canvas');\n this._hc.width = this._width;\n this._hc.height = this._height;\n this._hctx = this._hc.getContext('2d', {alpha: false});\n }\n\n this._canvas = el;\n this._ctx = this._canvas.getContext('2d', {alpha: false});\n this.update();\n }\n\n private update() {\n if(this._colors.length < 2) {\n const color = this._colors[0];\n this._ctx.fillStyle = `rgb(${color.r}, ${color.g}, ${color.b})`;\n this._ctx.fillRect(0, 0, this._width, this._height);\n return;\n }\n\n const pos = this.curPosition(this._phase, this._tail);\n this.drawGradient(pos);\n }\n\n public toNextPosition(getProgress?: () => number) {\n if(this._colors.length < 2) {\n return;\n }\n\n if(getProgress) {\n this._nextPositionLeft = this._tails + (this._nextPositionLeft ?? 0);\n this._nextPositionTails = this._nextPositionLeft;\n this._nextPositionTail = undefined;\n this._animatingToNextPosition = true;\n animateSingle(this.drawNextPositionAnimated.bind(this, getProgress), this);\n return;\n }\n\n const tail = this._tail;\n const tails = this._tails;\n\n let nextPhaseOnIdx: number;\n\n const curve: number[] = [];\n for(let i = 0, length = this._incrementalCurve.length; i < length; ++i) {\n const inc = this._incrementalCurve[i];\n let value = (curve[i - 1] ?? tail) + inc;\n\n if(+value.toFixed(2) > tails && nextPhaseOnIdx === undefined) {\n nextPhaseOnIdx = i;\n value %= tails;\n }\n\n curve.push(value);\n }\n\n const currentPhaseCurve = curve.slice(0, nextPhaseOnIdx);\n const nextPhaseCurve = nextPhaseOnIdx !== undefined ? curve.slice(nextPhaseOnIdx) : [];\n\n [currentPhaseCurve, nextPhaseCurve].forEach((curve, idx, curves) => {\n const last = curve[curve.length - 1];\n if(last !== undefined && last > tails) {\n curve[curve.length - 1] = +last.toFixed(2);\n }\n\n this._tail = last ?? 0;\n\n if(!curve.length) {\n return;\n }\n\n const positions = this.getNextPositions(this._phase, tails, curve);\n if(idx !== (curves.length - 1)) {\n if(++this._phase >= this._phases) {\n this._phase -= this._phases;\n }\n }\n\n const ids = positions.map((pos) => {\n return this.getGradientImageData(pos);\n });\n\n this._frames.push(...ids);\n });\n\n this._animatingToNextPosition = true;\n animateSingle(this.drawNextPositionAnimated, this);\n }\n\n // public toNextPositionThrottled = throttle(this.toNextPosition.bind(this), 100, true);\n\n public scrollAnimate(start?: boolean) {\n return;\n\n if(this._colors.length < 2 && start) {\n return;\n }\n\n if(start && !this._addedScrollListener) {\n document.addEventListener('wheel', this.onWheel);\n this._addedScrollListener = true;\n } else if(!start && this._addedScrollListener) {\n document.removeEventListener('wheel', this.onWheel);\n this._addedScrollListener = false;\n }\n }\n\n public cleanup() {\n this.scrollAnimate(false);\n // this.animate(false);\n }\n\n public static createCanvas(colors?: string) {\n const canvas = document.createElement('canvas');\n canvas.width = WIDTH;\n canvas.height = HEIGHT;\n if(colors !== undefined) {\n canvas.dataset.colors = colors;\n }\n\n return canvas;\n }\n\n public static create(colors?: string) {\n const canvas = this.createCanvas(colors);\n const gradientRenderer = new ChatBackgroundGradientRenderer();\n gradientRenderer.init(canvas);\n\n return {gradientRenderer, canvas};\n }\n}\n","export default function easeOutQuad(t: number, b: number, c: number, d: number) {\n return t >= d ? b + c : easeOutQuadApply(t / d, c) + b;\n}\n\nexport function easeOutQuadApply(v: number, c: number) {\n return -c * v * (v - 2);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type Chat from '../chat/chat';\nimport PopupElement from '.';\nimport CheckboxField from '../checkboxField';\nimport InputField from '../inputField';\nimport RadioField from '../radioField';\nimport Scrollable from '../scrollable';\nimport SendContextMenu from '../chat/sendContextMenu';\nimport I18n, {_i18n} from '../../lib/langPack';\nimport findUpTag from '../../helpers/dom/findUpTag';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport isInputEmpty from '../../helpers/dom/isInputEmpty';\nimport whichChild from '../../helpers/dom/whichChild';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport {Poll} from '../../layer';\nimport getRichValueWithCaret from '../../helpers/dom/getRichValueWithCaret';\n\nconst MAX_LENGTH_QUESTION = 255;\nconst MAX_LENGTH_OPTION = 100;\nconst MAX_LENGTH_SOLUTION = 200;\n\nexport default class PopupCreatePoll extends PopupElement {\n private questionInputField: InputField;\n private questions: HTMLElement;\n protected scrollable: Scrollable;\n private tempId = 0;\n\n private anonymousCheckboxField: CheckboxField;\n private multipleCheckboxField: PopupCreatePoll['anonymousCheckboxField'];\n private quizCheckboxField: PopupCreatePoll['anonymousCheckboxField'];\n\n private correctAnswers: Uint8Array[];\n private quizSolutionField: InputField;\n private optionInputFields: InputField[];\n\n constructor(private chat: Chat) {\n super('popup-create-poll popup-new-media', {closable: true, withConfirm: 'Create', body: true, title: 'NewPoll'});\n this.construct();\n }\n\n private async construct() {\n this.questionInputField = new InputField({\n placeholder: 'AskAQuestion',\n label: 'AskAQuestion',\n name: 'question',\n maxLength: MAX_LENGTH_QUESTION\n });\n\n this.listenerSetter.add(this.questionInputField.input)('input', () => {\n this.handleChange();\n });\n\n this.optionInputFields = [];\n\n if(this.chat.type !== 'scheduled') {\n const sendMenu = new SendContextMenu({\n onSilentClick: () => {\n this.chat.input.sendSilent = true;\n this.send();\n },\n onScheduleClick: () => {\n this.chat.input.scheduleSending(() => {\n this.send();\n });\n },\n openSide: 'bottom-left',\n onContextElement: this.btnConfirm\n });\n\n sendMenu.setPeerId(this.chat.peerId);\n\n this.header.append(sendMenu.sendMenu);\n }\n\n this.header.append(this.questionInputField.container);\n\n const hr = document.createElement('hr');\n const d = document.createElement('div');\n d.classList.add('caption');\n _i18n(d, 'PollOptions');\n\n this.questions = document.createElement('form');\n this.questions.classList.add('poll-create-questions');\n\n const dd = document.createElement('div');\n dd.classList.add('poll-create-settings');\n\n const settingsCaption = document.createElement('div');\n settingsCaption.classList.add('caption');\n _i18n(settingsCaption, 'Settings');\n\n if(!(await this.chat.managers.appPeersManager.isBroadcast(this.chat.peerId))) {\n this.anonymousCheckboxField = new CheckboxField({\n text: 'NewPoll.Anonymous',\n name: 'anonymous'\n });\n this.anonymousCheckboxField.input.checked = true;\n dd.append(this.anonymousCheckboxField.label);\n }\n\n this.multipleCheckboxField = new CheckboxField({\n text: 'NewPoll.MultipleChoice',\n name: 'multiple'\n });\n this.quizCheckboxField = new CheckboxField({\n text: 'NewPoll.Quiz',\n name: 'quiz'\n });\n\n this.listenerSetter.add(this.multipleCheckboxField.input)('change', () => {\n const checked = this.multipleCheckboxField.input.checked;\n this.quizCheckboxField.input.toggleAttribute('disabled', checked);\n });\n\n this.listenerSetter.add(this.quizCheckboxField.input)('change', () => {\n const checked = this.quizCheckboxField.input.checked;\n\n (Array.from(this.questions.children) as HTMLElement[]).map((el) => {\n el.classList.toggle('radio-field', checked);\n });\n\n if(!checked) {\n this.correctAnswers = undefined;\n this.quizSolutionField.setValueSilently('');\n }\n\n quizElements.forEach((el) => el.classList.toggle('hide', !checked));\n\n this.multipleCheckboxField.input.toggleAttribute('disabled', checked);\n this.handleChange();\n });\n\n dd.append(this.multipleCheckboxField.label, this.quizCheckboxField.label);\n\n const quizElements: HTMLElement[] = [];\n\n const quizSolutionCaption = document.createElement('div');\n quizSolutionCaption.classList.add('caption');\n _i18n(quizSolutionCaption, 'AccDescrQuizExplanation');\n\n const quizHr = document.createElement('hr');\n\n const quizSolutionContainer = document.createElement('div');\n quizSolutionContainer.classList.add('poll-create-questions');\n\n this.quizSolutionField = new InputField({\n placeholder: 'NewPoll.Explanation.Placeholder',\n label: 'NewPoll.Explanation.Placeholder',\n name: 'solution',\n maxLength: MAX_LENGTH_SOLUTION\n });\n\n this.listenerSetter.add(this.questionInputField.input)('input', () => {\n this.handleChange();\n });\n\n const quizSolutionSubtitle = document.createElement('div');\n quizSolutionSubtitle.classList.add('subtitle');\n _i18n(quizSolutionSubtitle, 'AddAnExplanationInfo');\n\n quizSolutionContainer.append(this.quizSolutionField.container, quizSolutionSubtitle);\n\n quizElements.push(quizHr, quizSolutionCaption, quizSolutionContainer);\n quizElements.forEach((el) => el.classList.add('hide'));\n\n this.body.parentElement.insertBefore(hr, this.body);\n this.body.append(d, this.questions, document.createElement('hr'), settingsCaption, dd, ...quizElements);\n\n attachClickEvent(this.btnConfirm, this.onSubmitClick, {listenerSetter: this.listenerSetter});\n\n this.scrollable = new Scrollable(this.body);\n this.appendMoreField();\n\n this.onEscape = () => {\n return !this.getFilledAnswers().length;\n };\n\n this.handleChange();\n }\n\n private getFilledAnswers() {\n const answers = Array.from(this.questions.children).map((el, idx) => {\n const input = el.querySelector('.input-field-input') as HTMLElement;\n return input instanceof HTMLInputElement ? input.value : getRichValueWithCaret(input, false, false).value;\n }).filter((v) => !!v.trim());\n\n return answers;\n }\n\n private onSubmitClick = () => {\n this.send();\n };\n\n private validate() {\n const question = this.questionInputField.value;\n if(!question) {\n return false;\n }\n\n if(question.length > MAX_LENGTH_QUESTION) {\n return false;\n }\n\n if(this.quizCheckboxField.input.checked && !this.correctAnswers?.length) {\n return false;\n }\n\n const answers = this.getFilledAnswers();\n if(answers.length < 2) {\n return false;\n }\n\n const tooLongOption = answers.find((a) => a.length > MAX_LENGTH_OPTION);\n if(tooLongOption) {\n return false;\n }\n\n const {value: quizSolution} = getRichValueWithCaret(this.quizSolutionField.input, false, false);\n if(quizSolution.length > MAX_LENGTH_SOLUTION) {\n return false;\n }\n\n return true;\n }\n\n private handleChange() {\n const valid = this.validate();\n this.btnConfirm.toggleAttribute('disabled', !valid);\n }\n\n public async send(force = false) {\n const question = this.questionInputField.value;\n\n const answers = this.getFilledAnswers();\n\n const {value: quizSolution, entities: quizSolutionEntities} = getRichValueWithCaret(this.quizSolutionField.input, true, false);\n\n if(this.chat.type === 'scheduled' && !force) {\n this.chat.input.scheduleSending(() => {\n this.send(true);\n });\n\n return;\n }\n\n this.hide();\n\n // const randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];\n // const randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString();\n\n const pFlags: Poll['pFlags'] = {};\n\n if(this.anonymousCheckboxField && !this.anonymousCheckboxField.input.checked) {\n pFlags.public_voters = true;\n }\n\n if(this.multipleCheckboxField.input.checked) {\n pFlags.multiple_choice = true;\n }\n\n if(this.quizCheckboxField.input.checked) {\n pFlags.quiz = true;\n }\n\n const poll: Poll = {\n _: 'poll',\n pFlags,\n question,\n answers: answers.map((value, idx) => {\n return {\n _: 'pollAnswer',\n text: value,\n option: new Uint8Array([idx])\n };\n }),\n id: undefined\n };\n // poll.id = randomIDS;\n\n const inputMediaPoll = await this.chat.managers.appPollsManager.getInputMediaPoll(poll, this.correctAnswers, quizSolution, quizSolutionEntities);\n\n // console.log('Will try to create poll:', inputMediaPoll);\n\n this.chat.managers.appMessagesManager.sendOther(this.chat.peerId, inputMediaPoll, {\n ...this.chat.getMessageSendingParams()\n });\n\n if(this.chat.input.helperType === 'reply') {\n this.chat.input.clearHelper();\n }\n\n this.chat.input.onMessageSent(false, false);\n }\n\n onInput = (e: Event) => {\n const target = e.target as HTMLInputElement;\n\n const radioLabel = findUpTag(target, 'LABEL');\n const isEmpty = isInputEmpty(target);\n if(!isEmpty) {\n target.parentElement.classList.add('is-filled');\n radioLabel.classList.remove('hidden-widget');\n radioLabel.firstElementChild.removeAttribute('disabled');\n }\n\n const isLast = !radioLabel.nextElementSibling;\n if(isLast && !isEmpty && this.questions.childElementCount < 10) {\n this.appendMoreField();\n }\n\n this.handleChange();\n };\n\n onDeleteClick = (e: MouseEvent) => {\n const target = e.target as HTMLSpanElement;\n const label = findUpTag(target, 'LABEL');\n const idx = whichChild(label);\n\n if(this.correctAnswers && this.correctAnswers[0][0] === idx) {\n this.correctAnswers = undefined;\n }\n\n label.remove();\n this.optionInputFields.splice(idx, 1);\n\n this.optionInputFields.forEach((inputField, idx) => {\n inputField.options.labelOptions.length = 0;\n inputField.options.labelOptions.push(idx + 1);\n const i18nElement = I18n.weakMap.get(inputField.label.firstElementChild as HTMLElement);\n i18nElement.update();\n });\n\n this.handleChange();\n };\n\n private appendMoreField() {\n const tempId = this.tempId++;\n const idx = this.questions.childElementCount + 1;\n const questionField = new InputField({\n placeholder: 'NewPoll.OptionsAddOption',\n label: 'NewPoll.OptionLabel',\n labelOptions: [idx],\n name: 'question-' + tempId,\n maxLength: MAX_LENGTH_OPTION\n });\n this.listenerSetter.add(questionField.input)('input', this.onInput);\n\n const radioField = new RadioField({\n text: '',\n name: 'question'\n });\n radioField.main.append(questionField.container);\n attachClickEvent(questionField.input, cancelEvent, {listenerSetter: this.listenerSetter});\n radioField.label.classList.add('hidden-widget');\n radioField.input.disabled = true;\n if(!this.quizCheckboxField.input.checked) {\n radioField.label.classList.remove('radio-field');\n }\n this.listenerSetter.add(radioField.input)('change', () => {\n const checked = radioField.input.checked;\n if(checked) {\n const idx = whichChild(radioField.label);\n this.correctAnswers = [new Uint8Array([idx])];\n this.handleChange();\n }\n });\n\n const deleteBtn = document.createElement('span');\n deleteBtn.classList.add('btn-icon', 'tgico-close');\n questionField.container.append(deleteBtn);\n\n attachClickEvent(deleteBtn, this.onDeleteClick, {listenerSetter: this.listenerSetter, once: true});\n\n this.questions.append(radioField.label);\n\n this.scrollable.scrollIntoViewNew({\n element: this.questions.lastElementChild as HTMLElement,\n position: 'center'\n });\n // this.scrollable.scrollTo(this.scrollable.scrollHeight, 'top', true, true);\n\n this.optionInputFields.push(questionField);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport fastSmoothScroll from '../fastSmoothScroll';\nimport cancelEvent from './cancelEvent';\nimport {attachClickEvent} from './clickEvent';\nimport findUpAsChild from './findUpAsChild';\nimport findUpClassName from './findUpClassName';\n\ntype ArrowKey = 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight';\nconst HANDLE_EVENT = 'keydown';\nconst ACTIVE_CLASS_NAME = 'active';\n\nconst AXIS_Y_KEYS: ArrowKey[] = ['ArrowUp', 'ArrowDown'];\nconst AXIS_X_KEYS: ArrowKey[] = ['ArrowLeft', 'ArrowRight'];\n\nexport type ListNavigationOptions = {\n list: HTMLElement,\n type: 'xy' | 'x' | 'y',\n onSelect: (target: Element) => void | boolean | Promise<boolean>,\n once: boolean,\n waitForKey?: string[]\n};\n\nexport default function attachListNavigation({list, type, onSelect, once, waitForKey}: ListNavigationOptions) {\n let waitForKeySet = waitForKey?.length ? new Set(waitForKey) : undefined;\n const keyNames = new Set(type === 'xy' ? AXIS_Y_KEYS.concat(AXIS_X_KEYS) : (type === 'x' ? AXIS_X_KEYS : AXIS_Y_KEYS));\n\n let target: Element;\n const getCurrentTarget = () => {\n return target || list.querySelector('.' + ACTIVE_CLASS_NAME) || list.firstElementChild;\n };\n\n const setCurrentTarget = (_target: Element, scrollTo: boolean) => {\n if(target === _target) {\n return;\n }\n\n let hadTarget = false;\n if(target) {\n hadTarget = true;\n target.classList.remove(ACTIVE_CLASS_NAME);\n }\n\n target = _target;\n if(!target) return;\n target.classList.add(ACTIVE_CLASS_NAME);\n\n if(hadTarget && scrollable && scrollTo) {\n fastSmoothScroll({\n container: scrollable,\n element: target as HTMLElement,\n position: 'center',\n forceDuration: 100,\n axis: type === 'x' ? 'x' : 'y'\n });\n }\n };\n\n const getNextTargetX = (currentTarget: Element, isNext: boolean) => {\n let nextTarget: Element;\n if(isNext) nextTarget = currentTarget.nextElementSibling || list.firstElementChild;\n else nextTarget = currentTarget.previousElementSibling || list.lastElementChild;\n\n return nextTarget;\n };\n\n const getNextTargetY = (currentTarget: Element, isNext: boolean) => {\n const property = isNext ? 'nextElementSibling' : 'previousElementSibling';\n const endProperty = isNext ? 'firstElementChild' : 'lastElementChild';\n const currentRect = currentTarget.getBoundingClientRect();\n\n let nextTarget = currentTarget[property] || list[endProperty];\n while(nextTarget !== currentTarget) {\n const targetRect = nextTarget.getBoundingClientRect();\n if(targetRect.x === currentRect.x && targetRect.y !== currentRect.y) {\n break;\n }\n\n nextTarget = nextTarget[property] || list[endProperty];\n }\n\n return nextTarget;\n };\n\n let handleArrowKey: (currentTarget: Element, key: ArrowKey) => Element;\n if(type === 'xy') { // flex-direction: row; flex-wrap: wrap;\n handleArrowKey = (currentTarget, key) => {\n if(key === 'ArrowUp' || key === 'ArrowDown') return getNextTargetY(currentTarget, key === 'ArrowDown');\n else return getNextTargetX(currentTarget, key === 'ArrowRight');\n };\n } else { // flex-direction: row | column;\n handleArrowKey = (currentTarget, key) => getNextTargetX(currentTarget, key === 'ArrowRight' || key === 'ArrowDown');\n }\n\n let onKeyDown = (e: KeyboardEvent) => {\n const key = e.key;\n if(!keyNames.has(key as any)) {\n if(key === 'Enter' || (type !== 'xy' && key === 'Tab')) {\n cancelEvent(e);\n fireSelect(getCurrentTarget());\n }\n\n return;\n }\n\n cancelEvent(e);\n\n if(list.childElementCount > 1) {\n let currentTarget = getCurrentTarget();\n currentTarget = handleArrowKey(currentTarget, key as any);\n setCurrentTarget(currentTarget, true);\n }\n };\n\n const scrollable = findUpClassName(list, 'scrollable');\n list.classList.add('navigable-list');\n\n const onMouseMove = (e: MouseEvent) => {\n const target = findUpAsChild(e.target as HTMLElement, list) as HTMLElement;\n if(!target) {\n return;\n }\n\n setCurrentTarget(target, false);\n };\n\n const onClick = (e: Event) => {\n cancelEvent(e); // cancel keyboard closening\n\n const target = findUpAsChild(e.target as HTMLElement, list) as HTMLElement;\n if(!target) {\n return;\n }\n\n setCurrentTarget(target, false);\n fireSelect(getCurrentTarget());\n };\n\n const fireSelect = async(target: Element) => {\n const canContinue = await onSelect(target);\n if(canContinue !== undefined ? !canContinue : once) {\n detach();\n }\n };\n\n let attached = false, detachClickEvent: () => void;\n const attach = () => {\n if(attached) return;\n attached = true;\n // const input = document.activeElement as HTMLElement;\n // input.addEventListener(HANDLE_EVENT, onKeyDown, {capture: true, passive: false});\n document.addEventListener(HANDLE_EVENT, onKeyDown, {capture: true, passive: false});\n list.addEventListener('mousemove', onMouseMove, {passive: true});\n detachClickEvent = attachClickEvent(list, onClick);\n };\n\n const detach = () => {\n if(!attached) return;\n attached = false;\n // input.removeEventListener(HANDLE_EVENT, onKeyDown, {capture: true});\n document.removeEventListener(HANDLE_EVENT, onKeyDown, {capture: true});\n list.removeEventListener('mousemove', onMouseMove);\n detachClickEvent();\n detachClickEvent = undefined;\n };\n\n const resetTarget = () => {\n if(waitForKeySet) return;\n setCurrentTarget(list.firstElementChild, false);\n };\n\n if(waitForKeySet) {\n const _onKeyDown = onKeyDown;\n onKeyDown = (e) => {\n if(waitForKeySet.has(e.key)) {\n cancelEvent(e);\n\n document.removeEventListener(HANDLE_EVENT, onKeyDown, {capture: true});\n onKeyDown = _onKeyDown;\n document.addEventListener(HANDLE_EVENT, onKeyDown, {capture: true, passive: false});\n\n waitForKeySet = undefined;\n resetTarget();\n }\n };\n } else {\n resetTarget();\n }\n\n attach();\n\n return {\n attach,\n detach,\n resetTarget\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport attachListNavigation, {ListNavigationOptions} from '../../helpers/dom/attachListNavigation';\nimport EventListenerBase from '../../helpers/eventListenerBase';\nimport {IS_MOBILE} from '../../environment/userAgent';\nimport rootScope from '../../lib/rootScope';\nimport appNavigationController, {NavigationItem} from '../appNavigationController';\nimport SetTransition from '../singleTransition';\nimport AutocompleteHelperController from './autocompleteHelperController';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport liteMode from '../../helpers/liteMode';\n\nexport default class AutocompleteHelper extends EventListenerBase<{\n hidden: () => void,\n visible: () => void,\n hiding: () => void\n}> {\n protected hidden = true;\n protected container: HTMLElement;\n protected list: HTMLElement;\n protected resetTarget: () => void;\n protected attach: () => void;\n protected detach: () => void;\n protected init?(): void;\n\n protected controller: AutocompleteHelperController;\n protected listType: 'xy' | 'x' | 'y';\n protected onSelect: ListNavigationOptions['onSelect'];\n protected waitForKey?: string[];\n\n protected navigationItem: NavigationItem;\n\n constructor(options: {\n appendTo: HTMLElement,\n controller?: AutocompleteHelper['controller'],\n listType: AutocompleteHelper['listType'],\n onSelect: AutocompleteHelper['onSelect'],\n waitForKey?: AutocompleteHelper['waitForKey']\n }) {\n super(false);\n\n safeAssign(this, options);\n\n this.container = document.createElement('div');\n this.container.classList.add('autocomplete-helper', 'z-depth-1');\n\n options.appendTo.append(this.container);\n\n this.attachNavigation();\n\n this.controller?.addHelper(this);\n }\n\n public toggleListNavigation(enabled: boolean) {\n if(enabled) {\n this.attach?.();\n } else {\n this.detach?.();\n }\n }\n\n protected onVisible = () => {\n this.detach?.(); // it can be so because 'visible' calls before animation's end\n\n const list = this.list;\n const {attach, detach, resetTarget} = attachListNavigation({\n list,\n type: this.listType,\n onSelect: this.onSelect,\n once: true,\n waitForKey: this.waitForKey\n });\n\n this.attach = attach;\n this.detach = detach;\n this.resetTarget = resetTarget;\n if(!IS_MOBILE && !this.navigationItem) {\n this.navigationItem = {\n type: 'autocomplete-helper',\n onPop: () => {\n this.navigationItem = undefined;\n this.toggle(true);\n },\n noBlurOnPop: true\n };\n\n appNavigationController.pushItem(this.navigationItem);\n }\n\n this.addEventListener('hidden', () => {\n this.resetTarget = undefined;\n this.attach = undefined;\n this.detach = undefined;\n\n list.replaceChildren();\n detach();\n\n if(this.navigationItem) {\n appNavigationController.removeItem(this.navigationItem);\n this.navigationItem = undefined;\n }\n }, {once: true});\n };\n\n protected attachNavigation() {\n this.addEventListener('visible', this.onVisible);\n }\n\n public toggle(hide?: boolean, fromController = false, skipAnimation?: boolean) {\n if(this.init) {\n return;\n }\n\n if(hide === undefined) {\n hide = this.container.classList.contains('is-visible') && !this.container.classList.contains('backwards');\n }\n\n if(this.hidden === hide) {\n if(!hide) {\n this.dispatchEvent('visible'); // reset target and listener\n }\n\n return;\n }\n\n this.hidden = hide;\n\n if(!hide) {\n this.controller && this.controller.hideOtherHelpers(this);\n this.dispatchEvent('visible'); // fire it before so target will be set\n } else {\n if(this.navigationItem) {\n appNavigationController.removeItem(this.navigationItem);\n this.navigationItem = undefined;\n }\n\n if(!fromController && this.controller) {\n this.controller.hideOtherHelpers();\n }\n\n this.detach?.(); // force detach here\n }\n\n const useRafs = this.controller || hide ? 0 : 2;\n\n if(hide) {\n this.dispatchEvent('hiding');\n }\n\n SetTransition({\n element: this.container,\n className: 'is-visible',\n forwards: !hide,\n duration: liteMode.isAvailable('animations') && !skipAnimation ? 300 : 0,\n onTransitionEnd: () => {\n this.hidden && this.dispatchEvent('hidden');\n },\n useRafs\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type Chat from './chat';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport preloadAnimatedEmojiSticker from '../../helpers/preloadAnimatedEmojiSticker';\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport rootScope from '../../lib/rootScope';\nimport {EmoticonsDropdown} from '../emoticonsDropdown';\nimport {SuperStickerRenderer} from '../emoticonsDropdown/tabs/stickers';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport Scrollable from '../scrollable';\nimport attachStickerViewerListeners from '../stickerViewer';\nimport AutocompleteHelper from './autocompleteHelper';\nimport AutocompleteHelperController from './autocompleteHelperController';\n\nexport default class StickersHelper extends AutocompleteHelper {\n private scrollable: Scrollable;\n private superStickerRenderer: SuperStickerRenderer;\n private lazyLoadQueue: LazyLoadQueue;\n private onChangeScreen: () => void;\n private listenerSetter: ListenerSetter;\n\n constructor(\n appendTo: HTMLElement,\n controller: AutocompleteHelperController,\n private chat: Chat,\n private managers: AppManagers\n ) {\n super({\n appendTo,\n controller,\n listType: 'xy',\n onSelect: async(target) => {\n return !(await EmoticonsDropdown.onMediaClick({target}, true));\n },\n waitForKey: ['ArrowUp', 'ArrowDown']\n });\n\n this.container.classList.add('stickers-helper');\n\n this.addEventListener('visible', () => {\n setTimeout(() => { // it is not rendered yet\n this.scrollable.container.scrollTop = 0;\n }, 0);\n\n rootScope.dispatchEvent('choosing_sticker', true);\n });\n\n this.addEventListener('hidden', () => {\n if(this.onChangeScreen) {\n mediaSizes.removeEventListener('changeScreen', this.onChangeScreen);\n this.onChangeScreen = undefined;\n\n this.listenerSetter.removeAll();\n this.listenerSetter = undefined;\n }\n\n rootScope.dispatchEvent('choosing_sticker', false);\n });\n }\n\n public checkEmoticon(emoticon: string) {\n const middleware = this.controller.getMiddleware();\n\n this.lazyLoadQueue?.clear();\n\n preloadAnimatedEmojiSticker(emoticon);\n this.managers.appStickersManager.getStickersByEmoticon(emoticon, true, rootScope.settings.stickers.suggest === 'all')\n .then((stickers) => {\n if(!middleware()) {\n return;\n }\n\n if(this.init) {\n this.init();\n this.init = null;\n }\n\n const container = this.list.cloneNode() as HTMLElement;\n\n let ready: Promise<void>;\n\n this.lazyLoadQueue.clear();\n if(stickers.length) {\n ready = new Promise<void>((resolve) => {\n const promises: Promise<any>[] = [];\n stickers.forEach((sticker) => {\n container.append(this.superStickerRenderer.renderSticker(sticker as MyDocument, undefined, promises));\n });\n\n (Promise.all(promises) as Promise<any>).finally(resolve);\n });\n } else {\n ready = Promise.resolve();\n }\n\n ready.then(() => {\n this.list.replaceWith(container);\n this.list = container;\n\n if(!this.onChangeScreen) {\n this.onChangeScreen = () => {\n const width = (this.list.childElementCount * mediaSizes.active.esgSticker.width) + (this.list.childElementCount - 1 * 1);\n this.list.style.width = width + 'px';\n };\n mediaSizes.addEventListener('changeScreen', this.onChangeScreen);\n\n this.listenerSetter = new ListenerSetter();\n attachStickerViewerListeners({listenTo: this.container, listenerSetter: this.listenerSetter});\n }\n\n this.onChangeScreen();\n\n this.toggle(!stickers.length);\n this.scrollable.scrollTop = 0;\n });\n });\n }\n\n public init() {\n this.list = document.createElement('div');\n this.list.classList.add('stickers-helper-stickers', 'super-stickers');\n\n this.container.append(this.list);\n\n this.scrollable = new Scrollable(this.container);\n this.lazyLoadQueue = new LazyLoadQueue();\n this.superStickerRenderer = new SuperStickerRenderer(this.lazyLoadQueue, this.chat.animationGroup, this.managers);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport {SEND_WHEN_ONLINE_TIMESTAMP} from '../../lib/mtproto/constants';\nimport Button from '../button';\nimport PopupDatePicker from './datePicker';\n\nconst getMinDate = () => {\n const date = new Date();\n // date.setDate(date.getDate() - 1);\n date.setHours(0, 0, 0, 0);\n return date;\n};\n\nconst getMaxDate = () => {\n const date = new Date();\n date.setFullYear(date.getFullYear() + 1);\n date.setDate(date.getDate() - 1);\n return date;\n};\n\nconst checkDate = (date: Date) => {\n return date.getTime() > getMaxDate().getTime() ? new Date() : date;\n};\n\nexport default class PopupSchedule extends PopupDatePicker {\n constructor(initDate: Date, onPick: (timestamp: number) => void, canSendWhenOnline: boolean) {\n super(checkDate(initDate), onPick, {\n noButtons: true,\n noTitle: true,\n closable: true,\n withConfirm: true,\n minDate: getMinDate(),\n maxDate: getMaxDate(),\n withTime: true,\n showOverflowMonths: true,\n confirmShortcutIsSendShortcut: true,\n title: true\n });\n\n this.element.classList.add('popup-schedule');\n this.header.append(this.controlsDiv);\n this.title.replaceWith(this.monthTitle);\n this.body.append(this.btnConfirm);\n\n if(canSendWhenOnline) {\n const btnSendWhenOnline = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'Schedule.SendWhenOnline'});\n this.body.append(btnSendWhenOnline);\n\n attachClickEvent(btnSendWhenOnline, () => {\n onPick(SEND_WHEN_ONLINE_TIMESTAMP);\n this.hide();\n });\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ChatInput from './input';\nimport {appendEmoji, getEmojiFromElement} from '../emoticonsDropdown/tabs/emoji';\nimport {ScrollableX} from '../scrollable';\nimport AutocompleteHelper from './autocompleteHelper';\nimport AutocompleteHelperController from './autocompleteHelperController';\nimport {AppManagers} from '../../lib/appManagers/managers';\n\nexport default class EmojiHelper extends AutocompleteHelper {\n private scrollable: ScrollableX;\n\n constructor(\n appendTo: HTMLElement,\n controller: AutocompleteHelperController,\n chatInput: ChatInput,\n private managers: AppManagers\n ) {\n super({\n appendTo,\n controller,\n listType: 'x',\n onSelect: (target) => {\n chatInput.onEmojiSelected(getEmojiFromElement(target as any), true);\n }\n });\n\n this.container.classList.add('emoji-helper');\n }\n\n public init() {\n this.list = document.createElement('div');\n this.list.classList.add('emoji-helper-emojis', 'super-emojis');\n\n this.container.append(this.list);\n\n this.scrollable = new ScrollableX(this.container);\n\n this.addEventListener('visible', () => {\n setTimeout(() => { // it is not rendered yet\n this.scrollable.container.scrollLeft = 0;\n }, 0);\n });\n }\n\n public render(emojis: string[], waitForKey: boolean) {\n if(this.init) {\n if(!emojis.length) {\n return;\n }\n\n this.init();\n this.init = null;\n }\n\n emojis = emojis.slice(0, 80);\n\n if(emojis.length) {\n this.list.replaceChildren();\n emojis.forEach((emoji) => {\n appendEmoji(emoji, this.list, false, true);\n });\n }\n\n this.waitForKey = waitForKey ? ['ArrowUp', 'ArrowDown'] : undefined;\n this.toggle(!emojis.length);\n\n /* window.requestAnimationFrame(() => {\n this.container.style.width = (3 * 2) + (emojis.length * 44) + 'px';\n }); */\n }\n\n public checkQuery(query: string, firstChar: string) {\n const middleware = this.controller.getMiddleware();\n this.managers.appEmojiManager.getBothEmojiKeywords().then(async() => {\n if(!middleware()) {\n return;\n }\n\n const q = query.replace(/^:/, '');\n const emojis = await this.managers.appEmojiManager.searchEmojis(q);\n if(!middleware()) {\n return;\n }\n\n this.render(emojis, firstChar !== ':');\n // console.log(emojis);\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport AvatarElement from '../avatar';\nimport PeerTitle from '../peerTitle';\nimport Scrollable from '../scrollable';\nimport AutocompleteHelper from './autocompleteHelper';\nimport AutocompleteHelperController from './autocompleteHelperController';\n\nexport default class AutocompletePeerHelper extends AutocompleteHelper {\n protected static BASE_CLASS = 'autocomplete-peer-helper';\n protected static BASE_CLASS_LIST_ELEMENT = AutocompletePeerHelper.BASE_CLASS + '-list-element';\n private scrollable: Scrollable;\n\n constructor(\n appendTo: HTMLElement,\n controller: AutocompleteHelperController,\n protected className: string,\n onSelect: (target: Element) => boolean | void\n ) {\n super({\n appendTo,\n controller,\n listType: 'y',\n onSelect\n });\n\n this.container.classList.add(AutocompletePeerHelper.BASE_CLASS, className);\n }\n\n public init() {\n this.list = document.createElement('div');\n this.list.classList.add(AutocompletePeerHelper.BASE_CLASS + '-list', this.className + '-list');\n\n this.container.append(this.list);\n\n this.scrollable = new Scrollable(this.container);\n\n this.addEventListener('visible', () => {\n setTimeout(() => { // it is not rendered yet\n this.scrollable.container.scrollTop = 0;\n }, 0);\n });\n }\n\n public render(data: {peerId: PeerId, name?: string, description?: string}[], doNotShow?: boolean) {\n if(this.init) {\n if(!data.length) {\n return;\n }\n\n this.init();\n this.init = null;\n }\n\n if(data.length) {\n this.list.replaceChildren();\n data.forEach((d) => {\n const div = AutocompletePeerHelper.listElement({\n className: this.className,\n peerId: d.peerId,\n name: d.name,\n description: d.description\n });\n\n this.list.append(div);\n });\n }\n\n if(!doNotShow) {\n this.toggle(!data.length);\n }\n }\n\n public static listElement(options: {\n className: string,\n peerId: PeerId,\n name?: string,\n description?: string\n }) {\n const BASE = AutocompletePeerHelper.BASE_CLASS_LIST_ELEMENT;\n options.className += '-list-element';\n\n const div = document.createElement('div');\n div.classList.add(BASE, options.className);\n div.dataset.peerId = '' + options.peerId;\n\n const avatar = new AvatarElement();\n avatar.classList.add('avatar-30', BASE + '-avatar', options.className + '-avatar');\n avatar.updateWithOptions({\n isDialog: false,\n peerId: options.peerId\n });\n\n const name = document.createElement('div');\n name.classList.add(BASE + '-name', options.className + '-name');\n if(!options.name) {\n name.append(new PeerTitle({\n peerId: options.peerId,\n dialog: false,\n onlyFirstName: false,\n plainText: false\n }).element);\n } else {\n setInnerHTML(name, wrapEmojiText(options.name));\n }\n\n div.append(avatar, name);\n\n if(options.description) {\n const description = document.createElement('div');\n description.classList.add(BASE + '-description', options.className + '-description');\n setInnerHTML(description, wrapEmojiText(options.description));\n div.append(description);\n }\n\n return div;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ChatInput from './input';\nimport type {BotInfo, ChatFull, UserFull} from '../../layer';\nimport AutocompleteHelperController from './autocompleteHelperController';\nimport AutocompletePeerHelper from './autocompletePeerHelper';\nimport SearchIndex from '../../lib/searchIndex';\nimport {AppManagers} from '../../lib/appManagers/managers';\n\nexport function processPeerFullForCommands(peerId: PeerId, full: ChatFull.chatFull | ChatFull.channelFull | UserFull.userFull, query?: string) {\n const botInfos: BotInfo.botInfo[] = [].concat(full.bot_info);\n let index: SearchIndex<string>;\n\n if(query !== undefined) {\n index = new SearchIndex<string>({\n ignoreCase: true\n });\n }\n\n type T = {peerId: PeerId, name: string, description: string, index: number, command: string};\n const commands: Map<string, T> = new Map();\n botInfos.forEach((botInfo) => {\n if(!botInfo.commands) {\n return;\n }\n\n botInfo.commands.forEach(({command, description}, idx) => {\n const c = '/' + command;\n commands.set(command, {\n peerId: botInfo.user_id ? botInfo.user_id.toPeerId(false) : peerId,\n command: command,\n name: c,\n description: description,\n index: idx\n });\n\n if(index) {\n index.indexObject(command, c);\n }\n });\n });\n\n let out: T[];\n if(!index) {\n out = [...commands.values()];\n } else {\n const found = index.search(query);\n out = Array.from(found).map((command) => commands.get(command));\n }\n\n out = out.sort((a, b) => commands.get(a.command).index - commands.get(b.command).index);\n\n return out;\n}\n\nexport default class CommandsHelper extends AutocompletePeerHelper {\n constructor(\n appendTo: HTMLElement,\n controller: AutocompleteHelperController,\n chatInput: ChatInput,\n private managers: AppManagers\n ) {\n super(appendTo,\n controller,\n 'commands-helper',\n (target) => {\n const innerHTML = target.querySelector(`.${AutocompletePeerHelper.BASE_CLASS_LIST_ELEMENT}-name`).innerHTML;\n return chatInput.getReadyToSend(() => {\n chatInput.messageInput.innerHTML = innerHTML;\n chatInput.sendMessage(true);\n });\n }\n );\n }\n\n public async checkQuery(query: string, peerId: PeerId) {\n if(!(await this.managers.appUsersManager.isBot(peerId))) {\n return false;\n }\n\n const middleware = this.controller.getMiddleware();\n this.managers.appProfileManager.getProfileByPeerId(peerId).then((full) => {\n if(!middleware()) {\n return;\n }\n\n const filtered = processPeerFullForCommands(peerId, full, query);\n this.render(filtered);\n // console.log('found commands', found, filtered);\n });\n\n return true;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {getMiddleware} from '../../helpers/middleware';\nimport AutocompleteHelper from './autocompleteHelper';\n\nexport default class AutocompleteHelperController {\n private helpers: Set<AutocompleteHelper> = new Set();\n private middleware = getMiddleware();\n /* private tempId = 0;\n\n public incrementToggleCount() {\n return ++this.tempId;\n }\n\n public getToggleCount() {\n return this.tempId;\n } */\n\n public toggleListNavigation(enabled: boolean) {\n for(const helper of this.helpers) {\n helper.toggleListNavigation(enabled);\n }\n }\n\n public getMiddleware() {\n this.middleware.clean();\n return this.middleware.get();\n }\n\n public addHelper(helper: AutocompleteHelper) {\n this.helpers.add(helper);\n }\n\n public hideOtherHelpers(preserveHelper?: AutocompleteHelper) {\n this.helpers.forEach((helper) => {\n if(helper !== preserveHelper) {\n helper.toggle(true, true);\n }\n });\n\n if(!preserveHelper) {\n this.middleware.clean();\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ChatInput from './input';\nimport type {MessageEntity} from '../../layer';\nimport AutocompleteHelperController from './autocompleteHelperController';\nimport AutocompletePeerHelper from './autocompletePeerHelper';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getPeerActiveUsernames from '../../lib/appManagers/utils/peers/getPeerActiveUsernames';\nimport rootScope from '../../lib/rootScope';\n\nexport default class MentionsHelper extends AutocompletePeerHelper {\n constructor(\n appendTo: HTMLElement,\n controller: AutocompleteHelperController,\n chatInput: ChatInput,\n private managers: AppManagers\n ) {\n super(\n appendTo,\n controller,\n 'mentions-helper',\n (target) => {\n const userId = (target as HTMLElement).dataset.peerId.toUserId();\n const user = Promise.resolve(managers.appUsersManager.getUser(userId)).then((user) => {\n let str = '', entity: MessageEntity;\n const usernames = getPeerActiveUsernames(user);\n if(usernames[0]) {\n str = '@' + usernames[0];\n } else {\n str = user.first_name || user.last_name;\n entity = {\n _: 'messageEntityMentionName',\n length: str.length,\n offset: 0,\n user_id: user.id\n };\n }\n\n str += ' ';\n chatInput.insertAtCaret(str, entity);\n });\n }\n );\n }\n\n public checkQuery(query: string, peerId: PeerId, topMsgId: number) {\n const trimmed = query.trim(); // check that there is no whitespace\n if(query.length !== trimmed.length) return false;\n\n const middleware = this.controller.getMiddleware();\n this.managers.appProfileManager.getMentions(peerId && peerId.toChatId(), trimmed, topMsgId).then(async(peerIds) => {\n if(!middleware()) return;\n\n peerIds = peerIds.filter((peerId) => peerId !== rootScope.myId);\n\n // const username = trimmed.slice(1).toLowerCase();\n\n const p = peerIds.map(async(peerId) => {\n const user = await this.managers.appUsersManager.getUser(peerId);\n const usernames = getPeerActiveUsernames(user);\n // if(usernames.length && usernames.some((_username) => _username.toLowerCase() === username)) { // hide full matched suggestion\n // return;\n // }\n\n return {\n peerId,\n description: usernames[0] ? '@' + usernames[0] : undefined\n };\n });\n\n this.render((await Promise.all(p)).filter(Boolean));\n });\n\n return true;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ChatInput from './input';\nimport DropdownHover from '../../helpers/dropdownHover';\nimport {KeyboardButton, ReplyMarkup} from '../../layer';\nimport rootScope from '../../lib/rootScope';\nimport ListenerSetter, {Listener} from '../../helpers/listenerSetter';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport findUpAsChild from '../../helpers/dom/findUpAsChild';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport {getHeavyAnimationPromise} from '../../hooks/useHeavyAnimationCheck';\nimport confirmationPopup from '../confirmationPopup';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport Scrollable from '../scrollable';\n\nexport default class ReplyKeyboard extends DropdownHover {\n private static BASE_CLASS = 'reply-keyboard';\n private appendTo: HTMLElement;\n private listenerSetter: ListenerSetter;\n private managers: AppManagers;\n private btnHover: HTMLElement;\n private peerId: PeerId;\n private touchListener: Listener;\n private chatInput: ChatInput;\n private scrollable: Scrollable;\n\n constructor(options: {\n listenerSetter: ListenerSetter,\n managers: AppManagers,\n appendTo: HTMLElement,\n btnHover: HTMLElement,\n chatInput: ChatInput\n }) {\n super({\n element: document.createElement('div')\n });\n\n safeAssign(this, options);\n\n this.element.classList.add(ReplyKeyboard.BASE_CLASS);\n this.element.style.display = 'none';\n\n this.scrollable = new Scrollable();\n this.element.append(this.scrollable.container);\n\n this.attachButtonListener(this.btnHover, this.listenerSetter);\n this.listenerSetter.add(rootScope)('history_reply_markup', async({peerId}) => {\n if(this.peerId === peerId) {\n if(this.checkAvailability() && this.isActive()) {\n await this.render();\n }\n\n getHeavyAnimationPromise().then(() => {\n this.checkForceReply();\n });\n }\n });\n }\n\n public init() {\n this.appendTo.append(this.element);\n\n this.listenerSetter.add(this)('open', async() => {\n await this.render();\n\n if(IS_TOUCH_SUPPORTED) {\n this.touchListener = this.listenerSetter.add(document.body)('touchstart', this.onBodyTouchStart, {passive: false, capture: true}) as any as Listener;\n this.listenerSetter.add(this)('close', () => {\n this.listenerSetter.remove(this.touchListener);\n }, {once: true});\n }\n });\n\n attachClickEvent(this.element, (e) => {\n const target = findUpClassName(e.target, 'btn');\n if(!target) {\n return;\n }\n\n const type = target.dataset.type as KeyboardButton['_'];\n const {peerId} = this;\n switch(type) {\n case 'keyboardButtonRequestPhone': {\n confirmationPopup({\n titleLangKey: 'ShareYouPhoneNumberTitle',\n button: {\n langKey: 'OK'\n },\n descriptionLangKey: 'AreYouSureShareMyContactInfoBot'\n }).then(() => {\n this.managers.appMessagesManager.sendContact(peerId, rootScope.myId);\n });\n break;\n }\n\n default: {\n this.managers.appMessagesManager.sendText(peerId, target.dataset.text);\n break;\n }\n }\n\n this.toggle(false);\n }, {listenerSetter: this.listenerSetter});\n\n return super.init();\n }\n\n private onBodyTouchStart = (e: TouchEvent) => {\n const target = e.touches[0].target as HTMLElement;\n if(!findUpAsChild(target, this.element) && target !== this.btnHover) {\n cancelEvent(e);\n this.toggle(false);\n }\n };\n\n public async checkForceReply() {\n const replyMarkup = await this.getReplyMarkup();\n if(replyMarkup._ === 'replyKeyboardForceReply' &&\n !replyMarkup.pFlags.hidden &&\n !replyMarkup.pFlags.used) {\n replyMarkup.pFlags.used = true;\n this.chatInput.initMessageReply(replyMarkup.mid);\n }\n }\n\n private async getReplyMarkup(): Promise<ReplyMarkup> {\n return (await this.managers.appMessagesManager.getHistoryStorageTransferable(this.peerId)).replyMarkup ?? {\n _: 'replyKeyboardHide',\n pFlags: {}\n };\n }\n\n public async render(replyMarkup?: ReplyMarkup.replyKeyboardMarkup) {\n if(replyMarkup === undefined) {\n replyMarkup = await this.getReplyMarkup() as any;\n }\n\n this.scrollable.container.replaceChildren();\n\n for(const row of replyMarkup.rows) {\n const div = document.createElement('div');\n div.classList.add(ReplyKeyboard.BASE_CLASS + '-row');\n\n for(const button of row.buttons) {\n const btn = document.createElement('button');\n btn.classList.add(ReplyKeyboard.BASE_CLASS + '-button', 'btn');\n setInnerHTML(btn, wrapEmojiText(button.text));\n btn.dataset.text = button.text;\n btn.dataset.type = button._;\n div.append(btn);\n }\n\n this.scrollable.container.append(div);\n }\n }\n\n public async checkAvailability(replyMarkup?: ReplyMarkup) {\n if(replyMarkup === undefined) {\n replyMarkup = await this.getReplyMarkup();\n }\n\n const hide = replyMarkup._ === 'replyKeyboardHide' || !(replyMarkup as ReplyMarkup.replyInlineMarkup).rows?.length;\n this.btnHover.classList.toggle('hide', hide);\n\n if(hide) {\n this.toggle(false);\n }\n\n return !hide;\n }\n\n public setPeer(peerId: PeerId) {\n this.peerId = peerId;\n\n this.checkAvailability();\n this.checkForceReply();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type Chat from './chat';\nimport debounce from '../../helpers/schedulers/debounce';\nimport {WebDocument} from '../../layer';\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport Scrollable from '../scrollable';\nimport AutocompleteHelper from './autocompleteHelper';\nimport AutocompleteHelperController from './autocompleteHelperController';\nimport Button from '../button';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport {MyPhoto} from '../../lib/appManagers/appPhotosManager';\nimport assumeType from '../../helpers/assumeType';\nimport GifsMasonry from '../gifsMasonry';\nimport {SuperStickerRenderer} from '../emoticonsDropdown/tabs/stickers';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport readBlobAsDataURL from '../../helpers/blob/readBlobAsDataURL';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport renderMediaWithFadeIn from '../../helpers/dom/renderMediaWithFadeIn';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport wrapRichText from '../../lib/richTextProcessor/wrapRichText';\nimport generateQId from '../../lib/appManagers/utils/inlineBots/generateQId';\nimport appDownloadManager from '../../lib/appManagers/appDownloadManager';\nimport {AnimationItemGroup} from '../animationIntersector';\nimport wrapPhoto from '../wrappers/photo';\nimport {i18n} from '../../lib/langPack';\nimport {POSTING_NOT_ALLOWED_MAP} from './input';\n\nconst ANIMATION_GROUP: AnimationItemGroup = 'INLINE-HELPER';\n// const GRID_ITEMS = 5;\n\nexport default class InlineHelper extends AutocompleteHelper {\n private scrollable: Scrollable;\n private lazyLoadQueue: LazyLoadQueue;\n private gifsMasonry: GifsMasonry;\n private superStickerRenderer: SuperStickerRenderer;\n private onChangeScreen: () => void;\n public checkQuery: ReturnType<typeof debounce<InlineHelper['_checkQuery']>>;\n\n constructor(\n appendTo: HTMLElement,\n controller: AutocompleteHelperController,\n private chat: Chat,\n private managers: AppManagers\n ) {\n super({\n appendTo,\n controller,\n listType: 'xy',\n waitForKey: ['ArrowUp', 'ArrowDown'],\n onSelect: (target) => {\n if(!target) return false; // can happen when there is only button\n const {peerId, botId, queryId} = this.list.dataset;\n return this.chat.input.getReadyToSend(() => {\n const queryAndResultIds = generateQId(queryId, (target as HTMLElement).dataset.resultId);\n this.managers.appInlineBotsManager.sendInlineResult(peerId.toPeerId(), botId, queryAndResultIds, {\n ...this.chat.getMessageSendingParams(),\n clearDraft: true\n });\n\n this.chat.input.onMessageSent(true, true);\n });\n }\n });\n\n this.container.classList.add('inline-helper');\n\n this.addEventListener('visible', () => {\n setTimeout(() => { // it is not rendered yet\n this.scrollable.container.scrollTop = 0;\n }, 0);\n });\n\n this.checkQuery = debounce(this._checkQuery, 200, true, true);\n\n this.addEventListener('hidden', () => {\n if(this.onChangeScreen) {\n mediaSizes.removeEventListener('changeScreen', this.onChangeScreen);\n this.onChangeScreen = undefined;\n }\n });\n }\n\n public _checkQuery = async(peerId: PeerId, username: string, query: string, canSendInline: boolean) => {\n const middleware = this.controller.getMiddleware();\n\n const peer = await this.managers.appUsersManager.resolveUsername(username);\n if(!middleware()) {\n throw 'PEER_CHANGED';\n }\n\n if(peer._ !== 'user' || !peer.pFlags.bot) {\n throw 'NOT_A_BOT';\n }\n\n if(!canSendInline) {\n if(!middleware()) {\n throw 'PEER_CHANGED';\n }\n\n if(this.init) {\n this.init();\n this.init = null;\n }\n\n this.container.classList.add('cant-send');\n this.toggle(false);\n throw 'NO_INLINES';\n }\n\n const renderPromise = this.managers.appInlineBotsManager.getInlineResults(peerId, peer.id, query).then((botResults) => {\n if(!middleware()) {\n throw 'PEER_CHANGED';\n }\n\n if(this.init) {\n this.init();\n this.init = null;\n }\n\n const list = this.list.cloneNode() as HTMLElement;\n list.dataset.peerId = '' + peerId;\n list.dataset.botId = '' + peer.id;\n list.dataset.queryId = '' + botResults.query_id;\n\n const gifsMasonry = new GifsMasonry(null, ANIMATION_GROUP, this.scrollable, false);\n\n this.lazyLoadQueue.clear();\n this.superStickerRenderer.clear();\n\n const loadPromises: Promise<any>[] = [];\n const isGallery = !!botResults.pFlags.gallery;\n // botResults.results.length = 3;\n for(const item of botResults.results) {\n const container = document.createElement('div');\n container.classList.add('inline-helper-result');\n container.dataset.resultId = item.id;\n\n const preview = isGallery ? undefined : document.createElement('div');\n if(preview) {\n preview.classList.add('inline-helper-result-preview');\n\n container.append(preview);\n }\n\n list.append(container);\n\n if(!isGallery) {\n preview.classList.add('empty');\n setInnerHTML(preview, wrapEmojiText([...item.title.trim()][0]));\n\n const title = document.createElement('div');\n title.classList.add('inline-helper-result-title');\n setInnerHTML(title, wrapEmojiText(item.title));\n\n const description = document.createElement('div');\n description.classList.add('inline-helper-result-description');\n setInnerHTML(description, wrapRichText(item.description, {\n noCommands: true,\n noLinks: true\n }));\n\n container.append(title, description);\n\n const separator = document.createElement('div');\n separator.classList.add('inline-helper-separator');\n\n list.append(separator);\n } else {\n container.classList.add('grid-item');\n }\n\n if(item._ === 'botInlineResult') {\n if(item.thumb && item.thumb.mime_type.indexOf('image/') === 0) {\n let mediaContainer: HTMLElement;\n if(preview) {\n mediaContainer = document.createElement('div');\n preview.append(mediaContainer);\n } else {\n mediaContainer = container;\n }\n\n mediaContainer.classList.add('media-container');\n isGallery && mediaContainer.classList.add('no-border-radius');\n\n this.lazyLoadQueue.push({\n div: container,\n load: () => {\n return appDownloadManager.download({\n dcId: 4,\n location: {\n _: 'inputWebFileLocation',\n access_hash: (item.thumb as WebDocument.webDocument).access_hash,\n url: item.thumb.url\n },\n size: item.thumb.size,\n mimeType: item.thumb.mime_type\n }).then((blob) => {\n const image = new Image();\n image.classList.add('media-photo');\n readBlobAsDataURL(blob).then((dataURL) => {\n renderMediaWithFadeIn(mediaContainer, image, dataURL, true);\n });\n });\n }\n });\n }\n } else {\n const media = item.document as MyDocument || item.photo as MyPhoto;\n if((['sticker', 'gif'] as MyDocument['type'][]).includes((media as MyDocument)?.type) && isGallery) {\n assumeType<MyDocument>(media);\n\n if(media.type === 'gif') {\n gifsMasonry.add(media, container);\n } else if(media.type === 'sticker') {\n container.classList.add('super-sticker');\n this.superStickerRenderer.renderSticker(media, container, loadPromises);\n if(media.animated) {\n this.superStickerRenderer.observeAnimated(container);\n }\n }\n } else if(media) {\n const size = isGallery ? 48 : undefined;\n isGallery && container.classList.add('no-border-radius');\n wrapPhoto({\n photo: media,\n container: isGallery ? container : preview,\n boxWidth: size,\n boxHeight: size,\n middleware,\n lazyLoadQueue: this.lazyLoadQueue,\n loadPromises\n });\n }\n }\n }\n\n return Promise.all(loadPromises).then(() => {\n if(!middleware()) {\n gifsMasonry.clear();\n return;\n }\n\n list.classList.toggle('is-gallery', isGallery);\n list.classList.toggle('super-stickers', isGallery);\n this.container.classList.toggle('is-gallery', isGallery);\n\n /* if(isGallery) {\n list.style.gridTemplateColumns = `repeat(${Math.min(botResults.results.length, 4)}, 1fr)`;\n }\n\n this.container.style.setProperty('width', isGallery ? `${Math.min(botResults.results.length, 4) * 25}%` : '', 'important'); */\n\n const parent = this.list.parentElement;\n parent.textContent = '';\n if(botResults.switch_pm) {\n const btnSwitchToPM = Button('btn-primary btn-secondary btn-primary-transparent primary');\n setInnerHTML(btnSwitchToPM, wrapEmojiText(botResults.switch_pm.text));\n attachClickEvent(btnSwitchToPM, (e) => {\n this.chat.appImManager.setInnerPeer({peerId});\n this.managers.appInlineBotsManager.switchToPM(peerId, peer.id, botResults.switch_pm.start_param);\n });\n parent.append(btnSwitchToPM);\n }\n parent.append(this.list = list);\n this.container.classList.remove('cant-send');\n\n this.gifsMasonry?.detach();\n this.gifsMasonry = gifsMasonry;\n gifsMasonry.attach();\n\n if(!this.onChangeScreen) {\n this.onChangeScreen = () => {\n if(this.list.classList.contains('is-gallery')) {\n const width = (this.list.childElementCount * mediaSizes.active.popupSticker.width) + (this.list.childElementCount - 1 * 1);\n this.list.style.width = width + 'px';\n } else {\n this.list.style.width = '';\n }\n };\n mediaSizes.addEventListener('changeScreen', this.onChangeScreen);\n }\n\n this.onChangeScreen();\n\n this.toggle(!botResults.results.length && !botResults.switch_pm);\n this.scrollable.scrollTop = 0;\n });\n });\n\n return {user: peer, renderPromise};\n };\n\n public init() {\n this.list = document.createElement('div');\n this.list.classList.add('inline-helper-results');\n\n this.container.append(this.list);\n\n this.scrollable = new Scrollable(this.container);\n this.lazyLoadQueue = new LazyLoadQueue();\n this.superStickerRenderer = new SuperStickerRenderer(this.lazyLoadQueue, ANIMATION_GROUP, this.managers);\n\n const span = i18n(POSTING_NOT_ALLOWED_MAP['send_inline']);\n span.classList.add('inline-helper-cant-send');\n this.container.append(span);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ChatInput from './input';\nimport callbackify from '../../helpers/callbackify';\nimport AutocompletePeerHelper from './autocompletePeerHelper';\nimport {processPeerFullForCommands} from './commandsHelper';\nimport {AppManagers} from '../../lib/appManagers/managers';\n\nconst CLASS_NAME = 'bot-commands';\nexport default class ChatBotCommands extends AutocompletePeerHelper {\n private userId: UserId;\n\n constructor(\n appendTo: HTMLElement,\n chatInput: ChatInput,\n private managers: AppManagers\n ) {\n super(appendTo, undefined, CLASS_NAME, (target) => {\n const innerHTML = target.querySelector(`.${AutocompletePeerHelper.BASE_CLASS_LIST_ELEMENT}-name`).innerHTML;\n return chatInput.getReadyToSend(() => {\n chatInput.messageInput.innerHTML = innerHTML;\n chatInput.sendMessage(true);\n this.toggle(true);\n });\n });\n }\n\n public setUserId(userId: UserId, middleware: () => boolean) {\n if(this.userId === userId && this.list?.childElementCount) {\n this.toggle(false);\n return;\n }\n\n this.userId = userId;\n return callbackify(this.managers.appProfileManager.getProfile(userId), (full) => {\n if(!middleware()) return;\n const filtered = processPeerFullForCommands(userId.toPeerId(false), full);\n\n const PADDING_TOP = 8;\n // const PADDING_BOTTOM = 8;\n const PADDING_BOTTOM = 24;\n const height = filtered.length * 50 + PADDING_TOP + PADDING_BOTTOM;\n this.container.style.setProperty('--height', height + 'px');\n\n this.render(filtered);\n\n // this.container.style.top =\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AckedResult} from '../lib/mtproto/superMessagePort';\nimport {Modify} from '../types';\n\nexport default async function modifyAckedResult<T>(acked: AckedResult<T>): Promise<Modify<AckedResult<T>, {result: T | Promise<T>}>> {\n return {\n cached: acked.cached,\n result: acked.cached ? await acked.result : acked.result\n };\n}\n\nexport function modifyAckedPromise<T>(promise: Promise<AckedResult<T>>) {\n return promise.then(modifyAckedResult);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport callbackify from '../../helpers/callbackify';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport liteMode from '../../helpers/liteMode';\nimport {getMiddleware} from '../../helpers/middleware';\nimport {modifyAckedPromise} from '../../helpers/modifyAckedResult';\nimport {ChatFull} from '../../layer';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getPeerId from '../../lib/appManagers/utils/peers/getPeerId';\nimport {i18n} from '../../lib/langPack';\nimport {AckedResult} from '../../lib/mtproto/superMessagePort';\nimport rootScope from '../../lib/rootScope';\nimport AvatarElement from '../avatar';\nimport {ButtonMenuItemOptions, ButtonMenuSync} from '../buttonMenu';\nimport ButtonMenuToggle from '../buttonMenuToggle';\nimport PeerTitle from '../peerTitle';\nimport SetTransition from '../singleTransition';\nimport getChatMembersString from '../wrappers/getChatMembersString';\n\nconst SEND_AS_ANIMATION_DURATION = 300;\n\nexport default class ChatSendAs {\n private avatar: AvatarElement;\n private container: HTMLElement;\n private closeBtn: HTMLElement;\n private btnMenu: HTMLElement;\n private sendAsPeerIds: PeerId[];\n private sendAsPeerId: PeerId;\n private updatingPromise: ReturnType<ChatSendAs['updateManual']>;\n private middleware: ReturnType<typeof getMiddleware>;\n private listenerSetter: ListenerSetter;\n private peerId: PeerId;\n private addedListener: boolean;\n private buttons: ButtonMenuItemOptions[];\n\n constructor(\n private managers: AppManagers,\n private onReady: (container: HTMLElement, skipAnimation?: boolean) => void,\n private onChange: (sendAsPeerId: PeerId) => void\n ) {\n this.middleware = getMiddleware();\n this.listenerSetter = new ListenerSetter();\n this.construct();\n }\n\n private construct() {\n this.container = document.createElement('div');\n this.container.classList.add('new-message-send-as-container');\n\n this.closeBtn = document.createElement('div');\n this.closeBtn.classList.add('new-message-send-as-close', 'new-message-send-as-avatar', 'tgico-close');\n\n const sendAsButtons: ButtonMenuItemOptions[] = [{\n text: 'SendMessageAsTitle',\n onClick: undefined\n }];\n\n this.buttons = [];\n\n let previousAvatar: HTMLElement;\n const onSendAsMenuToggle = (visible: boolean) => {\n if(visible) {\n previousAvatar = this.avatar;\n }\n\n const isChanged = this.avatar !== previousAvatar;\n const useRafs = !visible && isChanged ? 2 : 0;\n\n SetTransition({\n element: this.closeBtn,\n className: 'is-visible',\n forwards: visible,\n duration: SEND_AS_ANIMATION_DURATION,\n useRafs\n });\n if(!isChanged) {\n SetTransition({\n element: previousAvatar,\n className: 'is-visible',\n forwards: !visible,\n duration: SEND_AS_ANIMATION_DURATION,\n useRafs\n });\n }\n };\n\n ButtonMenuToggle({\n buttonOptions: {noRipple: true},\n listenerSetter: this.listenerSetter,\n container: this.container,\n direction: 'top-right',\n buttons: sendAsButtons,\n onOpenBefore: () => {\n onSendAsMenuToggle(true);\n },\n onOpen: (e, btnMenu) => {\n sendAsButtons[0].element.classList.add('btn-menu-item-header');\n this.btnMenu = btnMenu as any;\n this.btnMenu.classList.add('scrollable', 'scrollable-y');\n this.btnMenu.append(...this.buttons.map((button) => button.element));\n },\n onClose: () => {\n onSendAsMenuToggle(false);\n },\n onCloseAfter: () => {\n this.btnMenu = undefined;\n }\n });\n\n this.container.append(this.closeBtn);\n }\n\n private async updateButtons(peerIds: PeerId[]) {\n const promises: Promise<ButtonMenuItemOptions>[] = peerIds.map(async(sendAsPeerId, idx) => {\n const textElement = document.createElement('div');\n\n const subtitle = document.createElement('div');\n subtitle.classList.add('btn-menu-item-subtitle');\n if(sendAsPeerId.isUser()) {\n subtitle.append(i18n('Chat.SendAs.PersonalAccount'));\n } else if(sendAsPeerId === this.peerId) {\n subtitle.append(i18n('VoiceChat.DiscussionGroup'));\n } else {\n subtitle.append(await getChatMembersString(sendAsPeerId.toChatId()));\n }\n\n textElement.append(\n new PeerTitle({peerId: sendAsPeerId}).element,\n subtitle\n );\n\n return {\n onClick: idx ? async() => {\n const currentPeerId = this.peerId;\n this.changeSendAsPeerId(sendAsPeerId);\n\n const middleware = this.middleware.get();\n const executeButtonsUpdate = () => {\n if(this.sendAsPeerId !== sendAsPeerId || !middleware()) return;\n const peerIds = this.sendAsPeerIds.slice();\n indexOfAndSplice(peerIds, sendAsPeerId);\n peerIds.unshift(sendAsPeerId);\n this.updateButtons(peerIds);\n };\n\n if(liteMode.isAvailable('animations')) {\n setTimeout(executeButtonsUpdate, 250);\n } else {\n executeButtonsUpdate();\n }\n\n // return;\n this.managers.appMessagesManager.saveDefaultSendAs(currentPeerId, sendAsPeerId);\n } : undefined,\n textElement\n };\n });\n\n const buttons = await Promise.all(promises);\n const btnMenu = ButtonMenuSync({buttons}/* , this.listenerSetter */);\n buttons.forEach((button, idx) => {\n const peerId = peerIds[idx];\n const avatar = new AvatarElement();\n avatar.classList.add('avatar-26', 'btn-menu-item-icon');\n avatar.updateWithOptions({peerId});\n\n if(!idx) {\n avatar.classList.add('active');\n }\n\n button.element.prepend(avatar);\n });\n\n this.buttons = buttons;\n\n // if already opened\n this.btnMenu?.append(...this.buttons.map((button) => button.element));\n }\n\n private async updateAvatar(sendAsPeerId: PeerId, skipAnimation?: boolean) {\n const previousAvatar = this.avatar;\n if(previousAvatar) {\n if(previousAvatar.peerId === sendAsPeerId) {\n return;\n }\n }\n\n if(!previousAvatar) {\n skipAnimation = true;\n }\n\n const useRafs = skipAnimation ? 0 : 2;\n const duration = skipAnimation ? 0 : SEND_AS_ANIMATION_DURATION;\n const avatar = this.avatar = new AvatarElement();\n avatar.classList.add('new-message-send-as-avatar', 'avatar-30');\n await avatar.updateWithOptions({\n isDialog: false,\n peerId: sendAsPeerId\n });\n\n SetTransition({\n element: avatar,\n className: 'is-visible',\n forwards: true,\n duration,\n useRafs\n });\n if(previousAvatar) {\n SetTransition({\n element: previousAvatar,\n className: 'is-visible',\n forwards: false,\n duration,\n onTransitionEnd: () => {\n previousAvatar.remove();\n },\n useRafs\n });\n }\n\n this.container.append(avatar);\n }\n\n private changeSendAsPeerId(sendAsPeerId: PeerId, skipAnimation?: boolean) {\n this.sendAsPeerId = sendAsPeerId;\n this.onChange(sendAsPeerId);\n return this.updateAvatar(sendAsPeerId, skipAnimation);\n }\n\n private getDefaultSendAs(): Promise<AckedResult<PeerId>> {\n // return rootScope.myId;\n return this.managers.acknowledged.appProfileManager.getChannelFull(this.peerId.toChatId()).then((acked) => {\n return {\n cached: acked.cached,\n result: acked.result.then((channelFull) => {\n return channelFull.default_send_as ? getPeerId(channelFull.default_send_as) : undefined\n })\n };\n });\n }\n\n public async updateManual(skipAnimation?: boolean): Promise<() => void> {\n const peerId = this.peerId;\n if(this.updatingPromise || !(await this.managers.appPeersManager.isChannel(peerId))) {\n return;\n }\n\n const middleware = this.middleware.get(() => {\n return !this.updatingPromise || this.updatingPromise === updatingPromise;\n });\n\n const {container} = this;\n const chatId = peerId.toChatId();\n const result = (await modifyAckedPromise(this.getDefaultSendAs())).result;\n // const result = Promise.resolve(this.getDefaultSendAs());\n\n const wasSkippingAnimation = skipAnimation;\n if(result instanceof Promise) {\n skipAnimation = undefined;\n }\n\n const auto = wasSkippingAnimation && !skipAnimation;\n\n const updatingPromise = this.updatingPromise = callbackify(result, async(sendAsPeerId) => {\n if(!middleware() || sendAsPeerId === undefined) return;\n\n await this.changeSendAsPeerId(sendAsPeerId, skipAnimation);\n if(!middleware()) return;\n\n this.managers.appChatsManager.getSendAs(chatId).then((sendAsPeers) => {\n if(!middleware()) return;\n\n const peers = sendAsPeers.filter((sendAsPeer) => !sendAsPeer.pFlags.premium_required).map((sendAsPeer) => sendAsPeer.peer);\n const peerIds = peers.map((peer) => getPeerId(peer));\n this.sendAsPeerIds = peerIds.slice();\n\n indexOfAndSplice(peerIds, sendAsPeerId);\n peerIds.unshift(sendAsPeerId);\n this.updateButtons(peerIds);\n });\n\n const callback = () => {\n this.onReady(container, skipAnimation);\n\n if(!this.addedListener) {\n this.listenerSetter.add(rootScope)('peer_full_update', (peerId) => {\n if(this.peerId === peerId) {\n this.update();\n }\n });\n\n this.addedListener = true;\n }\n };\n\n if(auto) {\n callback();\n return;\n }\n\n return callback;\n });\n\n updatingPromise.finally(() => {\n if(this.updatingPromise === updatingPromise) {\n this.updatingPromise = undefined;\n }\n });\n\n if(!auto) {\n return updatingPromise;\n }\n }\n\n public update(skipAnimation?: boolean) {\n return this.updateManual(skipAnimation).then((callback) => callback?.());\n }\n\n public setPeerId(peerId?: PeerId) {\n /* if(this.avatar) {\n this.avatar.remove();\n this.avatar = undefined;\n } */\n\n this.middleware.clean();\n this.updatingPromise = undefined;\n this.peerId = peerId;\n }\n\n public destroy() {\n this.container.remove();\n this.setPeerId();\n this.listenerSetter.removeAll();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport {AppImManager, APP_TABS} from '../../lib/appManagers/appImManager';\nimport type {MyDraftMessage} from '../../lib/appManagers/appDraftsManager';\nimport type Chat from './chat';\nimport Recorder from '../../../public/recorder.min';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\n// import Recorder from '../opus-recorder/dist/recorder.min';\nimport opusDecodeController from '../../lib/opusDecodeController';\nimport {ButtonMenuItemOptions, ButtonMenuItemOptionsVerifiable, ButtonMenuSync} from '../buttonMenu';\nimport emoticonsDropdown from '../emoticonsDropdown';\nimport PopupCreatePoll from '../popups/createPoll';\nimport PopupForward from '../popups/forward';\nimport PopupNewMedia from '../popups/newMedia';\nimport {toast, toastNew} from '../toast';\nimport {MessageEntity, DraftMessage, WebPage, Message, UserFull, AttachMenuPeerType} from '../../layer';\nimport StickersHelper from './stickersHelper';\nimport ButtonIcon from '../buttonIcon';\nimport ButtonMenuToggle from '../buttonMenuToggle';\nimport ListenerSetter, {Listener} from '../../helpers/listenerSetter';\nimport Button from '../button';\nimport PopupSchedule from '../popups/schedule';\nimport SendMenu from './sendContextMenu';\nimport rootScope from '../../lib/rootScope';\nimport PopupPinMessage from '../popups/unpinMessage';\nimport tsNow from '../../helpers/tsNow';\nimport appNavigationController, {NavigationItem} from '../appNavigationController';\nimport {IS_MOBILE, IS_MOBILE_SAFARI} from '../../environment/userAgent';\nimport I18n, {i18n, join, LangPackKey} from '../../lib/langPack';\nimport {generateTail} from './bubbles';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport ButtonCorner from '../buttonCorner';\nimport blurActiveElement from '../../helpers/dom/blurActiveElement';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport cancelSelection from '../../helpers/dom/cancelSelection';\nimport {attachClickEvent, simulateClickEvent} from '../../helpers/dom/clickEvent';\nimport isInputEmpty from '../../helpers/dom/isInputEmpty';\nimport isSendShortcutPressed from '../../helpers/dom/isSendShortcutPressed';\nimport placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd';\nimport {MarkdownType} from '../../helpers/dom/getRichElementValue';\nimport getRichValueWithCaret from '../../helpers/dom/getRichValueWithCaret';\nimport EmojiHelper from './emojiHelper';\nimport CommandsHelper from './commandsHelper';\nimport AutocompleteHelperController from './autocompleteHelperController';\nimport AutocompleteHelper from './autocompleteHelper';\nimport MentionsHelper from './mentionsHelper';\nimport fixSafariStickyInput from '../../helpers/dom/fixSafariStickyInput';\nimport ReplyKeyboard from './replyKeyboard';\nimport InlineHelper from './inlineHelper';\nimport debounce from '../../helpers/schedulers/debounce';\nimport noop from '../../helpers/noop';\nimport {putPreloader} from '../putPreloader';\nimport SetTransition from '../singleTransition';\nimport PeerTitle from '../peerTitle';\nimport {fastRaf} from '../../helpers/schedulers';\nimport PopupDeleteMessages from '../popups/deleteMessages';\nimport fixSafariStickyInputFocusing, {IS_STICKY_INPUT_BUGGED} from '../../helpers/dom/fixSafariStickyInputFocusing';\nimport PopupPeer from '../popups/peer';\nimport MEDIA_MIME_TYPES_SUPPORTED from '../../environment/mediaMimeTypesSupport';\nimport appMediaPlaybackController from '../appMediaPlaybackController';\nimport {BOT_START_PARAM, NULL_PEER_ID} from '../../lib/mtproto/mtproto_config';\nimport setCaretAt from '../../helpers/dom/setCaretAt';\nimport CheckboxField from '../checkboxField';\nimport DropdownHover from '../../helpers/dropdownHover';\nimport RadioForm from '../radioForm';\nimport findUpTag from '../../helpers/dom/findUpTag';\nimport toggleDisability from '../../helpers/dom/toggleDisability';\nimport callbackify from '../../helpers/callbackify';\nimport ChatBotCommands from './botCommands';\nimport copy from '../../helpers/object/copy';\nimport toHHMMSS from '../../helpers/string/toHHMMSS';\nimport documentFragmentToHTML from '../../helpers/dom/documentFragmentToHTML';\nimport PopupElement from '../popups';\nimport getEmojiEntityFromEmoji from '../../lib/richTextProcessor/getEmojiEntityFromEmoji';\nimport mergeEntities from '../../lib/richTextProcessor/mergeEntities';\nimport parseEntities from '../../lib/richTextProcessor/parseEntities';\nimport parseMarkdown from '../../lib/richTextProcessor/parseMarkdown';\nimport wrapDraftText from '../../lib/richTextProcessor/wrapDraftText';\nimport wrapDraft from '../wrappers/draft';\nimport wrapMessageForReply from '../wrappers/messageForReply';\nimport getServerMessageId from '../../lib/appManagers/utils/messageId/getServerMessageId';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport contextMenuController from '../../helpers/contextMenuController';\nimport {emojiFromCodePoints} from '../../vendor/emoji';\nimport {modifyAckedPromise} from '../../helpers/modifyAckedResult';\nimport ChatSendAs from './sendAs';\nimport filterAsync from '../../helpers/array/filterAsync';\nimport InputFieldAnimated from '../inputFieldAnimated';\nimport getStickerEffectThumb from '../../lib/appManagers/utils/stickers/getStickerEffectThumb';\nimport PopupStickers from '../popups/stickers';\nimport wrapPeerTitle from '../wrappers/peerTitle';\nimport wrapReply from '../wrappers/reply';\nimport {getEmojiFromElement} from '../emoticonsDropdown/tabs/emoji';\nimport hasMarkupInSelection from '../../helpers/dom/hasMarkupInSelection';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport RichInputHandler from '../../helpers/dom/richInputHandler';\nimport {insertRichTextAsHTML} from '../inputField';\nimport getCaretPosNew from '../../helpers/dom/getCaretPosNew';\nimport draftsAreEqual from '../../lib/appManagers/utils/drafts/draftsAreEqual';\nimport isSelectionEmpty from '../../helpers/dom/isSelectionEmpty';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport getAttachMenuBotIcon from '../../lib/appManagers/utils/attachMenuBots/getAttachMenuBotIcon';\nimport TelegramWebView from '../telegramWebView';\nimport forEachReverse from '../../helpers/array/forEachReverse';\nimport {MARKDOWN_ENTITIES} from '../../lib/richTextProcessor';\nimport IMAGE_MIME_TYPES_SUPPORTED from '../../environment/imageMimeTypesSupport';\nimport VIDEO_MIME_TYPES_SUPPORTED from '../../environment/videoMimeTypesSupport';\nimport {ChatRights} from '../../lib/appManagers/appChatsManager';\n\nconst RECORD_MIN_TIME = 500;\n\nexport const POSTING_NOT_ALLOWED_MAP: {[action in ChatRights]?: LangPackKey} = {\n send_voices: 'GlobalAttachVoiceRestricted',\n send_stickers: 'GlobalAttachStickersRestricted',\n send_gifs: 'GlobalAttachGifRestricted',\n send_media: 'GlobalAttachMediaRestricted',\n send_plain: 'GlobalSendMessageRestricted',\n send_polls: 'ErrorSendRestrictedPollsAll',\n send_inline: 'GlobalAttachInlineRestricted'\n};\n\ntype ChatInputHelperType = 'edit' | 'webpage' | 'forward' | 'reply';\n\nexport default class ChatInput {\n // private static AUTO_COMPLETE_REG_EXP = /(\\s|^)((?::|.)(?!.*[:@]).*|(?:[@\\/]\\S*))$/;\n private static AUTO_COMPLETE_REG_EXP = /(\\s|^)((?:(?:@|^\\/)\\S*)|(?::|^[^:@\\/])(?!.*[:@\\/]).*)$/;\n public messageInput: HTMLElement;\n public messageInputField: InputFieldAnimated;\n private fileInput: HTMLInputElement;\n private inputMessageContainer: HTMLDivElement;\n private btnSend: HTMLButtonElement;\n private btnCancelRecord: HTMLButtonElement;\n public lastUrl = '';\n private lastTimeType = 0;\n\n public chatInput: HTMLElement;\n public inputContainer: HTMLElement;\n public rowsWrapper: HTMLDivElement;\n private newMessageWrapper: HTMLDivElement;\n private btnToggleEmoticons: HTMLButtonElement;\n private btnToggleReplyMarkup: HTMLButtonElement;\n private btnSendContainer: HTMLDivElement;\n\n private replyKeyboard: ReplyKeyboard;\n\n private attachMenu: HTMLElement;\n private attachMenuButtons: ButtonMenuItemOptionsVerifiable[];\n\n private sendMenu: SendMenu;\n\n private replyElements: {\n container: HTMLElement,\n cancelBtn: HTMLButtonElement,\n iconBtn: HTMLButtonElement\n } = {} as any;\n\n private forwardElements: {\n changePeer: ButtonMenuItemOptions,\n showSender: ButtonMenuItemOptions,\n hideSender: ButtonMenuItemOptions,\n showCaption: ButtonMenuItemOptions,\n hideCaption: ButtonMenuItemOptions,\n container: HTMLElement,\n modifyArgs?: ButtonMenuItemOptions[]\n };\n private forwardHover: DropdownHover;\n private forwardWasDroppingAuthor: boolean;\n\n private getWebPagePromise: Promise<void>;\n public willSendWebPage: WebPage = null;\n private forwarding: {[fromPeerId: PeerId]: number[]};\n public replyToMsgId: number;\n public editMsgId: number;\n public editMessage: Message.message;\n private noWebPage: true;\n public scheduleDate: number;\n public sendSilent: true;\n public startParam: string;\n\n private recorder: any;\n public recording = false;\n private recordCanceled = false;\n private recordTimeEl: HTMLElement;\n private recordRippleEl: HTMLElement;\n private recordStartTime = 0;\n private recordingOverlayListener: Listener;\n private recordingNavigationItem: NavigationItem;\n\n // private scrollTop = 0;\n // private scrollOffsetTop = 0;\n // private scrollDiff = 0;\n\n public helperType: Exclude<ChatInputHelperType, 'webpage'>;\n private helperFunc: () => void | Promise<void>;\n private helperWaitingForward: boolean;\n\n public willAttachType: 'document' | 'media';\n\n private lockRedo = false;\n private canRedoFromHTML = '';\n private readonly undoHistory: string[] = [];\n private readonly executedHistory: string[] = [];\n private canUndoFromHTML = '';\n\n private autocompleteHelperController: AutocompleteHelperController;\n private stickersHelper: StickersHelper;\n private emojiHelper: EmojiHelper;\n private commandsHelper: CommandsHelper;\n private mentionsHelper: MentionsHelper;\n private inlineHelper: InlineHelper;\n private listenerSetter: ListenerSetter;\n\n private pinnedControlBtn: HTMLButtonElement;\n\n private goDownBtn: HTMLButtonElement;\n private goDownUnreadBadge: HTMLElement;\n private goMentionBtn: HTMLButtonElement;\n private goMentionUnreadBadge: HTMLSpanElement;\n private btnScheduled: HTMLButtonElement;\n\n private btnPreloader: HTMLButtonElement;\n\n private saveDraftDebounced: () => void;\n\n private fakeRowsWrapper: HTMLDivElement;\n\n private previousQuery: string;\n\n private releaseMediaPlayback: () => void;\n\n private botStartBtn: HTMLButtonElement;\n private rowsWrapperWrapper: HTMLDivElement;\n private controlContainer: HTMLElement;\n private fakeSelectionWrapper: HTMLDivElement;\n\n private fakeWrapperTo: HTMLElement;\n private toggleBotStartBtnDisability: () => void;\n\n private botCommandsToggle: HTMLElement;\n private botCommands: ChatBotCommands;\n private botCommandsIcon: HTMLDivElement;\n private hasBotCommands: boolean;\n\n // private activeContainer: HTMLElement;\n\n private sendAs: ChatSendAs;\n public sendAsPeerId: PeerId;\n\n private replyInTopicOverlay: HTMLDivElement;\n private restoreInputLock: () => void;\n\n constructor(\n private chat: Chat,\n private appImManager: AppImManager,\n private managers: AppManagers\n ) {\n this.listenerSetter = new ListenerSetter();\n }\n\n public construct() {\n this.chatInput = document.createElement('div');\n this.chatInput.classList.add('chat-input', 'hide');\n\n this.inputContainer = document.createElement('div');\n this.inputContainer.classList.add('chat-input-container');\n\n this.rowsWrapperWrapper = document.createElement('div');\n this.rowsWrapperWrapper.classList.add('rows-wrapper-wrapper');\n\n this.rowsWrapper = document.createElement('div');\n this.rowsWrapper.classList.add('rows-wrapper', 'chat-input-wrapper');\n\n this.rowsWrapperWrapper.append(this.rowsWrapper);\n\n const tail = generateTail();\n this.rowsWrapper.append(tail);\n\n const fakeRowsWrapper = this.fakeRowsWrapper = document.createElement('div');\n fakeRowsWrapper.classList.add('fake-wrapper', 'fake-rows-wrapper');\n\n const fakeSelectionWrapper = this.fakeSelectionWrapper = document.createElement('div');\n fakeSelectionWrapper.classList.add('fake-wrapper', 'fake-selection-wrapper');\n\n this.inputContainer.append(this.rowsWrapperWrapper, fakeRowsWrapper, fakeSelectionWrapper);\n this.chatInput.append(this.inputContainer);\n\n this.goDownBtn = ButtonCorner({icon: 'arrow_down', className: 'bubbles-corner-button chat-secondary-button bubbles-go-down hide'});\n this.inputContainer.append(this.goDownBtn);\n\n attachClickEvent(this.goDownBtn, (e) => {\n cancelEvent(e);\n this.chat.bubbles.onGoDownClick();\n }, {listenerSetter: this.listenerSetter});\n\n // * constructor end\n\n /* let setScrollTopTimeout: number;\n // @ts-ignore\n let height = window.visualViewport.height; */\n // @ts-ignore\n // this.listenerSetter.add(window.visualViewport)('resize', () => {\n // const scrollable = this.chat.bubbles.scrollable;\n // const wasScrolledDown = scrollable.isScrolledDown;\n\n // /* if(wasScrolledDown) {\n // this.saveScroll();\n // } */\n\n // // @ts-ignore\n // let newHeight = window.visualViewport.height;\n // const diff = height - newHeight;\n // const scrollTop = scrollable.scrollTop;\n // const needScrollTop = wasScrolledDown ? scrollable.scrollHeight : scrollTop + diff; // * wasScrolledDown это проверка для десктоп хрома, когда пропадает панель загрузок снизу\n\n // console.log('resize before', scrollable.scrollTop, scrollable.container.clientHeight, scrollable.scrollHeight, wasScrolledDown, scrollable.lastScrollTop, diff, needScrollTop);\n\n // scrollable.scrollTop = needScrollTop;\n\n // if(setScrollTopTimeout) clearTimeout(setScrollTopTimeout);\n // setScrollTopTimeout = window.setTimeout(() => {\n // const diff = height - newHeight;\n // const isScrolledDown = scrollable.scrollHeight - Math.round(scrollable.scrollTop + scrollable.container.offsetHeight + diff) <= 1;\n // height = newHeight;\n\n // scrollable.scrollTop = needScrollTop;\n\n // console.log('resize after', scrollable.scrollTop, scrollable.container.clientHeight, scrollable.scrollHeight, scrollable.isScrolledDown, scrollable.lastScrollTop, isScrolledDown);\n\n // /* if(isScrolledDown) {\n // scrollable.scrollTop = scrollable.scrollHeight;\n // } */\n\n // //scrollable.scrollTop += diff;\n // setScrollTopTimeout = 0;\n // }, 0);\n // });\n\n // ! Can't use it with resizeObserver\n /* this.listenerSetter.add(window.visualViewport)('resize', () => {\n const scrollable = this.chat.bubbles.scrollable;\n const wasScrolledDown = scrollable.isScrolledDown;\n\n // @ts-ignore\n let newHeight = window.visualViewport.height;\n const diff = height - newHeight;\n const needScrollTop = wasScrolledDown ? scrollable.scrollHeight : scrollable.scrollTop + diff; // * wasScrolledDown это проверка для десктоп хрома, когда пропадает панель загрузок снизу\n\n //console.log('resize before', scrollable.scrollTop, scrollable.container.clientHeight, scrollable.scrollHeight, wasScrolledDown, scrollable.lastScrollTop, diff, needScrollTop);\n\n scrollable.scrollTop = needScrollTop;\n height = newHeight;\n\n if(setScrollTopTimeout) clearTimeout(setScrollTopTimeout);\n setScrollTopTimeout = window.setTimeout(() => { // * try again for scrolled down Android Chrome\n scrollable.scrollTop = needScrollTop;\n\n //console.log('resize after', scrollable.scrollTop, scrollable.container.clientHeight, scrollable.scrollHeight, scrollable.isScrolledDown, scrollable.lastScrollTop, isScrolledDown);\n setScrollTopTimeout = 0;\n }, 0);\n }); */\n\n const c = this.controlContainer = document.createElement('div');\n c.classList.add('chat-input-control', 'chat-input-wrapper');\n this.inputContainer.append(c);\n }\n\n private createButtonIcon(...args: Parameters<typeof ButtonIcon>) {\n const button = ButtonIcon(...args);\n button.tabIndex = -1;\n return button;\n }\n\n public constructPeerHelpers() {\n this.replyElements.container = document.createElement('div');\n this.replyElements.container.classList.add('reply-wrapper');\n\n this.replyElements.iconBtn = this.createButtonIcon('');\n this.replyElements.cancelBtn = this.createButtonIcon('close reply-cancel', {noRipple: true});\n\n this.replyElements.container.append(this.replyElements.iconBtn, this.replyElements.cancelBtn);\n\n //\n\n const onHideAuthorClick = () => {\n isChangingAuthor = true;\n };\n\n const onHideCaptionClick = () => {\n isChangingAuthor = false;\n };\n\n const forwardElements: ChatInput['forwardElements'] = this.forwardElements = {} as any;\n let isChangingAuthor = false;\n const forwardButtons: ButtonMenuItemOptions[] = [\n forwardElements.showSender = {\n text: 'Chat.Alert.Forward.Action.Show1',\n onClick: onHideAuthorClick,\n checkForClose: () => this.canToggleHideAuthor(),\n checkboxField: new CheckboxField({checked: true})\n },\n forwardElements.hideSender = {\n text: 'Chat.Alert.Forward.Action.Hide1',\n onClick: onHideAuthorClick,\n checkForClose: () => this.canToggleHideAuthor(),\n checkboxField: new CheckboxField({checked: false})\n },\n forwardElements.showCaption = {\n text: 'Chat.Alert.Forward.Action.ShowCaption',\n onClick: onHideCaptionClick,\n checkboxField: new CheckboxField({checked: true})\n },\n forwardElements.hideCaption = {\n text: 'Chat.Alert.Forward.Action.HideCaption',\n onClick: onHideCaptionClick,\n checkboxField: new CheckboxField({checked: false})\n },\n forwardElements.changePeer = {\n text: 'Chat.Alert.Forward.Action.Another',\n onClick: () => {\n this.changeForwardRecipient();\n },\n icon: 'replace'\n }\n ];\n const forwardBtnMenu = forwardElements.container = ButtonMenuSync({\n buttons: forwardButtons,\n listenerSetter: this.listenerSetter\n });\n // forwardBtnMenu.classList.add('top-center');\n\n const children = Array.from(forwardBtnMenu.children) as HTMLElement[];\n const groups: {\n elements: HTMLElement[],\n onChange: (value: string, event: Event) => void\n }[] = [{\n elements: children.slice(0, 2),\n onChange: (value, e) => {\n const checked = !!+value;\n if(isChangingAuthor) {\n this.forwardWasDroppingAuthor = !checked;\n }\n\n const replyTitle = this.replyElements.container.querySelector('.reply-title');\n if(replyTitle) {\n const el = replyTitle.firstElementChild as HTMLElement;\n const i = I18n.weakMap.get(el) as I18n.IntlElement;\n const langPackKey: LangPackKey = forwardElements.showSender.checkboxField.checked ? 'Chat.Accessory.Forward' : 'Chat.Accessory.Hidden';\n i.key = langPackKey;\n i.update();\n }\n }\n }, {\n elements: children.slice(2, 4),\n onChange: (value) => {\n const checked = !!+value;\n let b: ButtonMenuItemOptions;\n if(checked && this.forwardWasDroppingAuthor !== undefined) {\n b = this.forwardWasDroppingAuthor ? forwardElements.hideSender : forwardElements.showSender;\n } else {\n b = checked ? forwardElements.showSender : forwardElements.hideSender;\n }\n\n b.checkboxField.checked = true;\n }\n }];\n groups.forEach((group) => {\n const container = RadioForm(group.elements.map((e) => {\n return {\n container: e,\n input: e.querySelector('input')\n };\n }), group.onChange);\n\n const hr = document.createElement('hr');\n container.append(hr);\n forwardBtnMenu.append(container);\n });\n\n forwardBtnMenu.append(forwardElements.changePeer.element);\n\n if(!IS_TOUCH_SUPPORTED) {\n const forwardHover = this.forwardHover = new DropdownHover({\n element: forwardBtnMenu\n });\n }\n\n forwardElements.modifyArgs = forwardButtons.slice(0, -1);\n this.replyElements.container.append(forwardBtnMenu);\n\n forwardElements.modifyArgs.forEach((b, idx) => {\n const {input} = b.checkboxField;\n input.type = 'radio';\n input.name = idx < 2 ? 'author' : 'caption';\n input.value = '' + +!(idx % 2);\n });\n\n //\n\n this.newMessageWrapper = document.createElement('div');\n this.newMessageWrapper.classList.add('new-message-wrapper');\n\n this.replyInTopicOverlay = document.createElement('div');\n this.replyInTopicOverlay.classList.add('reply-in-topic-overlay', 'hide');\n this.replyInTopicOverlay.append(i18n('Chat.Input.ReplyToAnswer'));\n\n this.btnToggleEmoticons = this.createButtonIcon('none toggle-emoticons', {noRipple: true});\n\n this.inputMessageContainer = document.createElement('div');\n this.inputMessageContainer.classList.add('input-message-container');\n\n this.goDownUnreadBadge = document.createElement('span');\n this.goDownUnreadBadge.classList.add('badge', 'badge-24', 'badge-primary');\n this.goDownBtn.append(this.goDownUnreadBadge);\n\n this.goMentionBtn = ButtonCorner({icon: 'mention', className: 'bubbles-corner-button chat-secondary-button bubbles-go-mention'});\n this.goMentionUnreadBadge = document.createElement('span');\n this.goMentionUnreadBadge.classList.add('badge', 'badge-24', 'badge-primary');\n this.goMentionBtn.append(this.goMentionUnreadBadge);\n this.inputContainer.append(this.goMentionBtn);\n\n attachClickEvent(this.goMentionBtn, (e) => {\n cancelEvent(e);\n const middleware = this.chat.bubbles.getMiddleware();\n this.managers.appMessagesManager.goToNextMention(this.chat.peerId, this.chat.threadId).then((mid) => {\n if(!middleware()) {\n return;\n }\n\n if(mid) {\n this.chat.setMessageId(mid);\n }\n });\n }, {listenerSetter: this.listenerSetter});\n\n this.btnScheduled = this.createButtonIcon('scheduled btn-scheduled float hide', {noRipple: true});\n\n attachClickEvent(this.btnScheduled, (e) => {\n this.appImManager.openScheduled(this.chat.peerId);\n }, {listenerSetter: this.listenerSetter});\n\n this.listenerSetter.add(rootScope)('scheduled_new', ({peerId}) => {\n if(this.chat.peerId !== peerId) {\n return;\n }\n\n this.btnScheduled.classList.remove('hide');\n });\n\n this.listenerSetter.add(rootScope)('scheduled_delete', ({peerId}) => {\n if(this.chat.peerId !== peerId) {\n return;\n }\n\n this.managers.appMessagesManager.getScheduledMessages(this.chat.peerId).then((value) => {\n this.btnScheduled.classList.toggle('hide', !value.length);\n });\n });\n\n this.btnToggleReplyMarkup = this.createButtonIcon('botcom toggle-reply-markup float hide', {noRipple: true});\n this.replyKeyboard = new ReplyKeyboard({\n appendTo: this.rowsWrapper,\n listenerSetter: this.listenerSetter,\n managers: this.managers,\n btnHover: this.btnToggleReplyMarkup,\n chatInput: this\n });\n this.listenerSetter.add(this.replyKeyboard)('open', () => this.btnToggleReplyMarkup.classList.add('active'));\n this.listenerSetter.add(this.replyKeyboard)('close', () => this.btnToggleReplyMarkup.classList.remove('active'));\n\n this.botCommands = new ChatBotCommands(this.rowsWrapper, this, this.managers);\n this.botCommandsToggle = document.createElement('div');\n this.botCommandsToggle.classList.add('new-message-bot-commands');\n\n const scaler = document.createElement('div');\n scaler.classList.add('new-message-bot-commands-icon-scale');\n\n const icon = this.botCommandsIcon = document.createElement('div');\n icon.classList.add('animated-menu-icon', 'animated-menu-close-icon');\n scaler.append(icon);\n this.botCommandsToggle.append(scaler);\n\n attachClickEvent(this.botCommandsToggle, (e) => {\n cancelEvent(e);\n const isShown = icon.classList.contains('state-back');\n if(isShown) {\n this.botCommands.toggle(true);\n icon.classList.remove('state-back');\n } else {\n this.botCommands.setUserId(this.chat.peerId.toUserId(), this.chat.bubbles.getMiddleware());\n icon.classList.add('state-back');\n }\n }, {listenerSetter: this.listenerSetter});\n\n this.botCommands.addEventListener('visible', () => {\n icon.classList.add('state-back');\n });\n\n this.botCommands.addEventListener('hiding', () => {\n icon.classList.remove('state-back');\n });\n\n // const getSendMediaRights = () => Promise.all([this.chat.canSend('send_photos'), this.chat.canSend('send_videos')]).then(([photos, videos]) => ({photos, videos}));\n\n const onAttachMediaClick = (photos: boolean, videos: boolean) => {\n this.fileInput.value = '';\n\n const accept = [\n ...(photos ? IMAGE_MIME_TYPES_SUPPORTED : []),\n ...(videos ? VIDEO_MIME_TYPES_SUPPORTED : [])\n ].join(', ');\n\n this.fileInput.setAttribute('accept', accept);\n this.willAttachType = 'media';\n this.fileInput.click();\n };\n\n this.attachMenuButtons = [{\n icon: 'image',\n text: 'Chat.Input.Attach.PhotoOrVideo',\n onClick: () => onAttachMediaClick(true, true)\n // verify: () => getSendMediaRights().then(({photos, videos}) => photos && videos)\n }, /* {\n icon: 'image',\n text: 'AttachPhoto',\n onClick: () => onAttachMediaClick(true, false),\n verify: () => getSendMediaRights().then(({photos, videos}) => photos && !videos)\n }, {\n icon: 'image',\n text: 'AttachVideo',\n onClick: () => onAttachMediaClick(false, true),\n verify: () => getSendMediaRights().then(({photos, videos}) => !photos && videos)\n }, */ {\n icon: 'document',\n text: 'Chat.Input.Attach.Document',\n onClick: () => {\n this.fileInput.value = '';\n this.fileInput.removeAttribute('accept');\n this.willAttachType = 'document';\n this.fileInput.click();\n }\n // verify: () => this.chat.canSend('send_docs')\n }, {\n icon: 'gift',\n text: 'GiftPremium',\n onClick: () => this.chat.appImManager.giftPremium(this.chat.peerId),\n verify: () => Promise.all([this.chat.canGiftPremium(), this.managers.apiManager.getAppConfig()]).then(([canGift, {premium_gift_attach_menu_icon}]) => canGift && premium_gift_attach_menu_icon)\n }, {\n icon: 'poll',\n text: 'Poll',\n onClick: async() => {\n const action: ChatRights = 'send_polls';\n if(!(await this.chat.canSend(action))) {\n toastNew({langPackKey: POSTING_NOT_ALLOWED_MAP[action]});\n return;\n }\n\n PopupElement.createPopup(PopupCreatePoll, this.chat).show();\n },\n verify: () => this.chat.peerId.isAnyChat() || this.chat.isBot\n }];\n\n // preload the bots\n this.managers.appAttachMenuBotsManager.getAttachMenuBots();\n\n const attachMenuButtons = this.attachMenuButtons.slice();\n this.attachMenu = ButtonMenuToggle({\n buttonOptions: {noRipple: true},\n listenerSetter: this.listenerSetter,\n direction: 'top-left',\n buttons: this.attachMenuButtons,\n onOpenBefore: async() => {\n const attachMenuBots = await this.managers.appAttachMenuBotsManager.getAttachMenuBots();\n const buttons = attachMenuButtons.slice();\n console.log(attachMenuBots);\n const attachMenuBotsButtons = attachMenuBots.filter((attachMenuBot) => {\n return !attachMenuBot.pFlags.inactive;\n }).map((attachMenuBot) => {\n const icon = getAttachMenuBotIcon(attachMenuBot);\n const button: typeof buttons[0] = {\n regularText: wrapEmojiText(attachMenuBot.short_name),\n onClick: () => {\n this.managers.appAttachMenuBotsManager.requestWebView({\n botId: attachMenuBot.bot_id,\n peerId: this.chat.peerId,\n ...this.chat.getMessageSendingParams()\n }).then((webViewResultUrl) => {\n const SANDBOX_ATTRIBUTES = [\n 'allow-scripts',\n 'allow-same-origin',\n 'allow-popups',\n 'allow-forms',\n 'allow-modals'\n // 'allow-storage-access-by-user-activation'\n ].join(' ');\n\n class P extends PopupElement<{\n finish: () => void\n }> {\n private telegramWebView: TelegramWebView;\n\n constructor(private url: string) {\n super('popup-payment popup-payment-verification', {\n closable: true,\n overlayClosable: true,\n body: true,\n titleRaw: attachMenuBot.short_name\n });\n\n this.d();\n }\n\n protected destroy() {\n this.telegramWebView.destroy();\n return super.destroy();\n }\n\n private d() {\n const telegramWebView = this.telegramWebView = new TelegramWebView({\n url: this.url,\n sandbox: SANDBOX_ATTRIBUTES\n });\n\n telegramWebView.iframe.classList.add('payment-verification');\n\n this.body.append(telegramWebView.iframe);\n this.show();\n telegramWebView.onMount();\n }\n }\n\n new P(webViewResultUrl.url);\n });\n },\n iconDoc: icon?.icon as MyDocument,\n verify: async() => {\n let found = false;\n\n const verifyMap: {\n [type in AttachMenuPeerType['_']]: () => boolean | Promise<boolean>\n } = {\n attachMenuPeerTypeSameBotPM: () => this.chat.peerId.toUserId() === attachMenuBot.bot_id,\n attachMenuPeerTypeBotPM: () => this.chat.isBot,\n attachMenuPeerTypePM: () => this.chat.peerId.isUser(),\n attachMenuPeerTypeChat: () => this.chat.isAnyGroup,\n attachMenuPeerTypeBroadcast: () => this.chat.isBroadcast\n };\n\n for(const peerType of attachMenuBot.peer_types) {\n const verify = verifyMap[peerType._];\n found = await verify();\n if(found) {\n break;\n }\n }\n\n return found;\n }\n };\n\n return button;\n });\n\n buttons.splice(buttons.length, 0, ...attachMenuBotsButtons);\n this.attachMenuButtons.splice(0, this.attachMenuButtons.length, ...buttons);\n }\n });\n this.attachMenu.classList.add('attach-file', 'tgico-attach');\n this.attachMenu.classList.remove('tgico-more');\n\n // this.inputContainer.append(this.sendMenu);\n\n this.recordTimeEl = document.createElement('div');\n this.recordTimeEl.classList.add('record-time');\n\n this.fileInput = document.createElement('input');\n this.fileInput.type = 'file';\n this.fileInput.multiple = true;\n this.fileInput.style.display = 'none';\n\n this.newMessageWrapper.append(...[this.botCommandsToggle, this.btnToggleEmoticons, this.inputMessageContainer, this.btnScheduled, this.btnToggleReplyMarkup, this.attachMenu, this.recordTimeEl, this.fileInput].filter(Boolean));\n\n this.rowsWrapper.append(this.replyElements.container);\n this.autocompleteHelperController = new AutocompleteHelperController();\n this.stickersHelper = new StickersHelper(this.rowsWrapper, this.autocompleteHelperController, this.chat, this.managers);\n this.emojiHelper = new EmojiHelper(this.rowsWrapper, this.autocompleteHelperController, this, this.managers);\n this.commandsHelper = new CommandsHelper(this.rowsWrapper, this.autocompleteHelperController, this, this.managers);\n this.mentionsHelper = new MentionsHelper(this.rowsWrapper, this.autocompleteHelperController, this, this.managers);\n this.inlineHelper = new InlineHelper(this.rowsWrapper, this.autocompleteHelperController, this.chat, this.managers);\n this.rowsWrapper.append(this.newMessageWrapper);\n\n this.btnCancelRecord = this.createButtonIcon('binfilled btn-circle btn-record-cancel chat-secondary-button');\n\n this.btnSendContainer = document.createElement('div');\n this.btnSendContainer.classList.add('btn-send-container');\n\n this.recordRippleEl = document.createElement('div');\n this.recordRippleEl.classList.add('record-ripple');\n\n this.btnSend = this.createButtonIcon('none btn-circle btn-send animated-button-icon');\n this.btnSend.insertAdjacentHTML('afterbegin', `\n <span class=\"tgico tgico-send\"></span>\n <span class=\"tgico tgico-schedule\"></span>\n <span class=\"tgico tgico-check\"></span>\n <span class=\"tgico tgico-microphone_filled\"></span>\n `);\n\n this.btnSendContainer.append(this.recordRippleEl, this.btnSend);\n\n this.sendMenu = new SendMenu({\n onSilentClick: () => {\n this.sendSilent = true;\n this.sendMessage();\n },\n onScheduleClick: () => {\n this.scheduleSending(undefined);\n },\n listenerSetter: this.listenerSetter,\n openSide: 'top-left',\n onContextElement: this.btnSend,\n onOpen: () => {\n return this.chat.type !== 'scheduled' && (!this.isInputEmpty() || !!Object.keys(this.forwarding).length);\n }\n });\n\n this.btnSendContainer.append(this.sendMenu.sendMenu);\n\n this.inputContainer.append(this.btnCancelRecord, this.btnSendContainer);\n\n emoticonsDropdown.attachButtonListener(this.btnToggleEmoticons, this.listenerSetter);\n this.listenerSetter.add(emoticonsDropdown)('open', this.onEmoticonsOpen);\n this.listenerSetter.add(emoticonsDropdown)('close', this.onEmoticonsClose);\n\n this.attachMessageInputField();\n\n /* this.attachMenu.addEventListener('mousedown', (e) => {\n const hidden = this.attachMenu.querySelectorAll('.hide');\n if(hidden.length === this.attachMenuButtons.length) {\n toast(POSTING_MEDIA_NOT_ALLOWED);\n cancelEvent(e);\n return false;\n }\n }, {passive: false, capture: true}); */\n\n this.listenerSetter.add(rootScope)('settings_updated', () => {\n if(this.stickersHelper || this.emojiHelper) {\n // this.previousQuery = undefined;\n this.previousQuery = '';\n this.checkAutocomplete();\n /* if(!rootScope.settings.stickers.suggest) {\n this.stickersHelper.checkEmoticon('');\n } else {\n this.onMessageInput();\n } */\n }\n\n this.messageInputField?.onFakeInput();\n });\n\n this.listenerSetter.add(rootScope)('draft_updated', ({peerId, threadId, draft, force}) => {\n if(this.chat.threadId !== threadId || this.chat.peerId !== peerId || this.chat.type === 'scheduled') return;\n this.setDraft(draft, true, force);\n });\n\n this.listenerSetter.add(this.appImManager)('peer_changing', (chat) => {\n if(this.chat === chat && (this.chat.type === 'chat' || this.chat.type === 'discussion')) {\n this.saveDraft();\n }\n });\n\n this.listenerSetter.add(this.appImManager)('chat_changing', ({from, to}) => {\n if(this.chat === from) {\n this.autocompleteHelperController.toggleListNavigation(false);\n } else if(this.chat === to) {\n this.autocompleteHelperController.toggleListNavigation(true);\n }\n });\n\n this.listenerSetter.add(rootScope)('scheduled_delete', ({peerId, mids}) => {\n if(this.chat.type === 'scheduled' && this.chat.peerId === peerId && mids.includes(this.editMsgId)) {\n this.onMessageSent();\n }\n });\n\n this.listenerSetter.add(rootScope)('history_delete', ({peerId, msgs}) => {\n if(this.chat.peerId === peerId && this.chat.type !== 'scheduled') {\n if(msgs.has(this.editMsgId)) {\n this.onMessageSent();\n }\n\n if(this.replyToMsgId && msgs.has(this.replyToMsgId)) {\n this.clearHelper('reply');\n }\n\n /* if(this.chat.isStartButtonNeeded()) {\n this.setStartParam(BOT_START_PARAM);\n } */\n }\n });\n\n this.listenerSetter.add(rootScope)('dialogs_multiupdate', (dialogs) => {\n if(dialogs.has(this.chat.peerId) && (this.chat.type === 'chat' || this.chat.type === 'discussion')) {\n if(this.startParam === BOT_START_PARAM) {\n this.setStartParam();\n } else { // updateNewMessage comes earlier than dialog appers\n this.center(true);\n }\n }\n });\n\n try {\n this.recorder = new Recorder({\n // encoderBitRate: 32,\n // encoderPath: \"../dist/encoderWorker.min.js\",\n encoderSampleRate: 48000,\n monitorGain: 0,\n numberOfChannels: 1,\n recordingGain: 1,\n reuseWorker: true\n });\n } catch(err) {\n console.error('Recorder constructor error:', err);\n }\n\n this.updateSendBtn();\n\n this.listenerSetter.add(this.fileInput)('change', (e) => {\n const files = (e.target as HTMLInputElement & EventTarget).files;\n if(!files.length) {\n return;\n }\n\n PopupElement.createPopup(PopupNewMedia, this.chat, Array.from(files).slice(), this.willAttachType);\n this.fileInput.value = '';\n }, false);\n\n /* let time = Date.now();\n this.btnSend.addEventListener('touchstart', (e) => {\n time = Date.now();\n });\n\n let eventName1 = 'touchend';\n this.btnSend.addEventListener(eventName1, (e: Event) => {\n //cancelEvent(e);\n console.log(eventName1 + ', time: ' + (Date.now() - time));\n });\n\n let eventName = 'mousedown';\n this.btnSend.addEventListener(eventName, (e: Event) => {\n cancelEvent(e);\n console.log(eventName + ', time: ' + (Date.now() - time));\n }); */\n attachClickEvent(this.btnSend, this.onBtnSendClick, {listenerSetter: this.listenerSetter, touchMouseDown: true});\n\n if(this.recorder) {\n attachClickEvent(this.btnCancelRecord, this.onCancelRecordClick, {listenerSetter: this.listenerSetter});\n\n this.recorder.onstop = () => {\n this.setRecording(false);\n this.chatInput.classList.remove('is-locked');\n this.recordRippleEl.style.transform = '';\n };\n\n this.recorder.ondataavailable = (typedArray: Uint8Array) => {\n if(this.releaseMediaPlayback) {\n this.releaseMediaPlayback();\n this.releaseMediaPlayback = undefined;\n }\n\n if(this.recordingOverlayListener) {\n this.listenerSetter.remove(this.recordingOverlayListener);\n this.recordingOverlayListener = undefined;\n }\n\n if(this.recordingNavigationItem) {\n appNavigationController.removeItem(this.recordingNavigationItem);\n this.recordingNavigationItem = undefined;\n }\n\n if(this.recordCanceled) {\n return;\n }\n\n const {peerId, threadId} = this.chat;\n const replyToMsgId = this.replyToMsgId;\n\n const duration = (Date.now() - this.recordStartTime) / 1000 | 0;\n const dataBlob = new Blob([typedArray], {type: 'audio/ogg'});\n /* const fileName = new Date().toISOString() + \".opus\";\n console.log('Recorder data received', typedArray, dataBlob); */\n\n // let perf = performance.now();\n opusDecodeController.decode(typedArray, true).then((result) => {\n // console.log('WAVEFORM!:', /* waveform, */performance.now() - perf);\n\n opusDecodeController.setKeepAlive(false);\n\n // тут objectURL ставится уже с audio/wav\n this.managers.appMessagesManager.sendFile(peerId, {\n file: dataBlob,\n isVoiceMessage: true,\n isMedia: true,\n duration,\n waveform: result.waveform,\n objectURL: result.url,\n replyToMsgId,\n threadId,\n clearDraft: true\n });\n\n this.onMessageSent(false, true);\n });\n };\n }\n\n attachClickEvent(this.replyElements.cancelBtn, this.onHelperCancel, {listenerSetter: this.listenerSetter});\n attachClickEvent(this.replyElements.container, this.onHelperClick, {listenerSetter: this.listenerSetter});\n\n this.saveDraftDebounced = debounce(() => this.saveDraft(), 2500, false, true);\n\n this.botStartBtn = Button('btn-primary btn-transparent text-bold chat-input-control-button');\n this.botStartBtn.append(i18n('BotStart'));\n\n attachClickEvent(this.botStartBtn, () => {\n const {startParam} = this;\n if(startParam === undefined) {\n return;\n }\n\n const toggle = this.toggleBotStartBtnDisability = toggleDisability([this.botStartBtn], true);\n const peerId = this.chat.peerId;\n const middleware = this.chat.bubbles.getMiddleware(() => {\n return this.chat.peerId === peerId && this.startParam === startParam && this.toggleBotStartBtnDisability === toggle;\n });\n\n this.managers.appMessagesManager.startBot(peerId.toUserId(), undefined, startParam).then(() => {\n if(middleware()) {\n toggle();\n this.toggleBotStartBtnDisability = undefined;\n this.setStartParam();\n }\n });\n }, {listenerSetter: this.listenerSetter});\n\n this.controlContainer.append(this.botStartBtn, this.replyInTopicOverlay);\n\n // * pinned part start\n this.pinnedControlBtn = Button('btn-primary btn-transparent text-bold chat-input-control-button', {icon: 'unpin'});\n this.controlContainer.append(this.pinnedControlBtn);\n\n this.listenerSetter.add(this.pinnedControlBtn)('click', () => {\n const peerId = this.chat.peerId;\n\n PopupElement.createPopup(PopupPinMessage, peerId, 0, true, () => {\n this.chat.appImManager.setPeer(); // * close tab\n\n // ! костыль, это скроет закреплённые сообщения сразу, вместо того, чтобы ждать пока анимация перехода закончится\n const originalChat = this.chat.appImManager.chat;\n if(originalChat.topbar.pinnedMessage) {\n originalChat.topbar.pinnedMessage.pinnedMessageContainer.toggle(true);\n }\n });\n });\n // * pinned part end\n }\n\n public _center(neededFakeContainer: HTMLElement, animate?: boolean) {\n if(!neededFakeContainer && !this.inputContainer.classList.contains('is-centering')) {\n return;\n }\n\n if(neededFakeContainer === this.fakeWrapperTo) {\n return;\n }\n\n /* if(neededFakeContainer === this.botStartContainer && this.fakeWrapperTo === this.fakeSelectionWrapper) {\n this.inputContainer.classList.remove('is-centering');\n void this.rowsWrapper.offsetLeft; // reflow\n // this.inputContainer.classList.add('is-centering');\n // void this.rowsWrapper.offsetLeft; // reflow\n } */\n\n const fakeSelectionWrapper = neededFakeContainer || this.fakeWrapperTo;\n const forwards = !!neededFakeContainer;\n const oldFakeWrapperTo = this.fakeWrapperTo;\n let transform = '', borderRadius = '', needTranslateX: number;\n // if(forwards) {]\n const fakeSelectionRect = fakeSelectionWrapper.getBoundingClientRect();\n const fakeRowsRect = this.fakeRowsWrapper.getBoundingClientRect();\n const widthFrom = fakeRowsRect.width;\n const widthTo = fakeSelectionRect.width;\n\n if(widthFrom !== widthTo) {\n const scale = (widthTo/* - 8 */) / widthFrom;\n const initTranslateX = (widthFrom - widthTo) / 2;\n needTranslateX = fakeSelectionRect.left - fakeRowsRect.left - initTranslateX;\n\n if(forwards) {\n transform = `translateX(${needTranslateX}px) scaleX(${scale})`;\n // transform = `translateX(0px) scaleX(${scale})`;\n\n if(scale < 1) {\n const br = 16;\n borderRadius = '' + (br + br * (1 - scale)) + 'px';\n }\n }\n // scale = widthTo / widthFrom;\n }\n // }\n\n this.fakeWrapperTo = neededFakeContainer;\n\n const duration = animate ? 200 : 0;\n SetTransition({\n element: this.inputContainer,\n className: 'is-centering',\n forwards,\n duration\n });\n SetTransition({\n element: this.rowsWrapperWrapper,\n className: 'is-centering-to-control',\n forwards: !!(forwards && neededFakeContainer && neededFakeContainer.classList.contains('chat-input-control')),\n duration\n });\n this.rowsWrapper.style.transform = transform;\n this.rowsWrapper.style.borderRadius = borderRadius;\n\n return {\n transform,\n borderRadius,\n needTranslateX: oldFakeWrapperTo && (\n (\n neededFakeContainer &&\n neededFakeContainer.classList.contains('chat-input-control') &&\n oldFakeWrapperTo === this.fakeSelectionWrapper\n ) || oldFakeWrapperTo.classList.contains('chat-input-control')\n ) ? needTranslateX * -.5 : needTranslateX,\n widthFrom,\n widthTo\n };\n }\n\n public async center(animate = false) {\n return this._center(await this.getNeededFakeContainer(), animate);\n }\n\n public setStartParam(startParam?: string) {\n if(this.startParam === startParam) {\n return;\n }\n\n this.startParam = startParam;\n this.center(true);\n }\n\n public isReplyInTopicOverlayNeeded() {\n return this.chat.isForum &&\n !this.chat.isForumTopic &&\n !this.replyToMsgId &&\n this.chat.type === 'chat';\n }\n\n public async getNeededFakeContainer(startParam = this.startParam) {\n if(this.chat.selection.isSelecting) {\n return this.fakeSelectionWrapper;\n } else if(\n startParam !== undefined ||\n // !(await this.chat.canSend()) || // ! WARNING, TEMPORARILY COMMENTED\n this.chat.type === 'pinned' ||\n await this.chat.isStartButtonNeeded() ||\n this.isReplyInTopicOverlayNeeded()\n ) {\n return this.controlContainer;\n }\n }\n\n // public getActiveContainer() {\n // if(this.chat.selection.isSelecting) {\n // return this.chat\n // }\n // return this.startParam !== undefined ? this.botStartContainer : this.rowsWrapper;\n // }\n\n // public setActiveContainer() {\n // const container = this.activeContainer;\n // const newContainer = this.getActiveContainer();\n // if(newContainer === container) {\n // return;\n // }\n\n\n // }\n\n private onCancelRecordClick = (e?: Event) => {\n if(e) {\n cancelEvent(e);\n }\n\n this.recordCanceled = true;\n this.recorder.stop();\n opusDecodeController.setKeepAlive(false);\n };\n\n private onEmoticonsOpen = () => {\n const toggleClass = IS_TOUCH_SUPPORTED ? 'flip-icon' : 'active';\n this.btnToggleEmoticons.classList.toggle(toggleClass, true);\n };\n\n private onEmoticonsClose = () => {\n const toggleClass = IS_TOUCH_SUPPORTED ? 'flip-icon' : 'active';\n this.btnToggleEmoticons.classList.toggle(toggleClass, false);\n };\n\n public getReadyToSend(callback: () => void) {\n return this.chat.type === 'scheduled' ? (this.scheduleSending(callback), true) : (callback(), false);\n }\n\n public scheduleSending = async(callback: () => void = this.sendMessage.bind(this, true), initDate = new Date()) => {\n const {peerId} = this.chat;\n const middleware = this.chat.bubbles.getMiddleware();\n const canSendWhenOnline = rootScope.myId !== peerId && peerId.isUser() && await this.managers.appUsersManager.isUserOnlineVisible(peerId);\n\n PopupElement.createPopup(PopupSchedule, initDate, (timestamp) => {\n if(!middleware()) {\n return;\n }\n\n const minTimestamp = (Date.now() / 1000 | 0) + 10;\n if(timestamp <= minTimestamp) {\n timestamp = undefined;\n }\n\n this.scheduleDate = timestamp;\n callback();\n\n if(this.chat.type !== 'scheduled' && timestamp) {\n setTimeout(() => { // ! need timeout here because .forwardMessages will be called after timeout\n if(!middleware()) {\n return;\n }\n\n const popups = PopupElement.getPopups(PopupStickers);\n popups.forEach((popup) => popup.hide());\n\n this.appImManager.openScheduled(peerId);\n }, 0);\n }\n }, canSendWhenOnline).show();\n };\n\n public async setUnreadCount() {\n if(!this.goDownUnreadBadge) {\n return;\n }\n\n const dialog = await this.managers.dialogsStorage.getDialogOrTopic(this.chat.peerId, this.chat.type === 'discussion' ? undefined : this.chat.threadId);\n const count = dialog?.unread_count;\n this.goDownUnreadBadge.innerText = '' + (count || '');\n this.goDownUnreadBadge.classList.toggle('badge-gray', await this.managers.appNotificationsManager.isPeerLocalMuted({peerId: this.chat.peerId, respectType: true, threadId: this.chat.threadId}));\n\n if(this.goMentionUnreadBadge && this.chat.type === 'chat') {\n const hasMentions = !!(dialog?.unread_mentions_count && dialog.unread_count);\n this.goMentionUnreadBadge.innerText = hasMentions ? '' + (dialog.unread_mentions_count) : '';\n this.goMentionBtn.classList.toggle('is-visible', hasMentions);\n }\n }\n\n public getCurrentInputAsDraft(ignoreEmptyValue?: boolean) {\n const {value, entities} = getRichValueWithCaret(this.messageInputField.input, true, false);\n\n let draft: DraftMessage.draftMessage;\n if((value.length || ignoreEmptyValue) || this.replyToMsgId) {\n draft = {\n _: 'draftMessage',\n date: tsNow(true),\n message: value,\n entities: entities.length ? entities : undefined,\n pFlags: {\n no_webpage: this.noWebPage\n },\n reply_to_msg_id: this.replyToMsgId\n };\n }\n\n return draft;\n }\n\n public saveDraft() {\n if(!this.chat.peerId || this.editMsgId || this.chat.type === 'scheduled') return;\n const draft = this.getCurrentInputAsDraft();\n this.managers.appDraftsManager.syncDraft(this.chat.peerId, this.chat.threadId, draft);\n }\n\n public destroy() {\n // this.chat.log.error('Input destroying');\n\n this.listenerSetter.removeAll();\n }\n\n public cleanup(helperToo = true) {\n if(!this.chat.peerId) {\n this.chatInput.classList.add('hide');\n this.goDownBtn.classList.add('hide');\n }\n\n cancelSelection();\n\n this.lastTimeType = 0;\n this.startParam = undefined;\n\n if(this.toggleBotStartBtnDisability) {\n this.toggleBotStartBtnDisability();\n this.toggleBotStartBtnDisability = undefined;\n }\n\n if(this.messageInput) {\n this.clearInput();\n helperToo && this.clearHelper();\n }\n }\n\n public async setDraft(draft?: MyDraftMessage, fromUpdate = true, force = false) {\n if((!force && !isInputEmpty(this.messageInput)) || this.chat.type === 'scheduled') return false;\n\n if(!draft) {\n draft = await this.managers.appDraftsManager.getDraft(this.chat.peerId, this.chat.threadId);\n\n if(!draft) {\n if(force) { // this situation can only happen when sending message with clearDraft\n /* const height = this.chatInput.getBoundingClientRect().height;\n const willChangeHeight = 78 - height;\n this.willChangeHeight = willChangeHeight; */\n if(this.chat.container.classList.contains('is-helper-active')) {\n this.t();\n }\n\n this.messageInputField.inputFake.textContent = '';\n this.messageInputField.onFakeInput(false);\n\n ((this.chat.bubbles.messagesQueuePromise || Promise.resolve()) as Promise<any>).then(() => {\n fastRaf(() => {\n this.onMessageSent();\n });\n });\n }\n\n return false;\n }\n }\n\n const wrappedDraft = wrapDraft(draft, this.chat.peerId);\n const currentDraft = this.getCurrentInputAsDraft();\n\n if(draftsAreEqual(draft, currentDraft) &&/* this.messageInputField.value === wrappedDraft && */this.replyToMsgId === draft.reply_to_msg_id) return false;\n\n if(fromUpdate) {\n this.clearHelper();\n }\n\n this.noWebPage = draft.pFlags.no_webpage;\n if(draft.reply_to_msg_id) {\n this.initMessageReply(draft.reply_to_msg_id);\n }\n\n this.setInputValue(wrappedDraft, fromUpdate, fromUpdate);\n return true;\n }\n\n private createSendAs() {\n this.sendAsPeerId = undefined;\n\n if(this.chat.type === 'chat' || this.chat.type === 'discussion') {\n let firstChange = true;\n this.sendAs = new ChatSendAs(\n this.managers,\n (container, skipAnimation) => {\n let useRafs = 0;\n if(!container.parentElement) {\n this.newMessageWrapper.prepend(container);\n useRafs = 2;\n }\n\n this.updateOffset('as', true, skipAnimation, useRafs);\n },\n (sendAsPeerId) => {\n this.sendAsPeerId = sendAsPeerId;\n\n // do not change placeholder earlier than finishPeerChange does\n if(firstChange) {\n firstChange = false;\n return;\n }\n\n this.getPlaceholderKey().then((key) => {\n this.updateMessageInputPlaceholder(key);\n });\n }\n );\n } else {\n this.sendAs = undefined;\n }\n\n return this.sendAs;\n }\n\n public async finishPeerChange(options: Parameters<Chat['finishPeerChange']>[0]) {\n const peerId = this.chat.peerId;\n const {startParam, middleware} = options;\n\n const {\n forwardElements,\n btnScheduled,\n replyKeyboard,\n sendMenu,\n goDownBtn,\n chatInput,\n botCommandsToggle,\n attachMenu\n } = this;\n\n const previousSendAs = this.sendAs;\n const sendAs = this.createSendAs();\n const filteredAttachMenuButtons = this.filterAttachMenuButtons();\n\n const [\n isBroadcast,\n canPinMessage,\n isBot,\n canSend,\n canSendPlain,\n neededFakeContainer,\n ackedPeerFull,\n ackedScheduledMids,\n setSendAsCallback\n ] = await Promise.all([\n this.managers.appPeersManager.isBroadcast(peerId),\n this.managers.appPeersManager.canPinMessage(peerId),\n this.managers.appPeersManager.isBot(peerId),\n this.chat.canSend('send_messages'),\n this.chat.canSend('send_plain'),\n this.getNeededFakeContainer(startParam),\n modifyAckedPromise(this.managers.acknowledged.appProfileManager.getProfileByPeerId(peerId)),\n btnScheduled ? modifyAckedPromise(this.managers.acknowledged.appMessagesManager.getScheduledMessages(peerId)) : undefined,\n sendAs ? (sendAs.setPeerId(this.chat.peerId), sendAs.updateManual(true)) : undefined\n ]);\n\n const placeholderKey = this.messageInput ? await this.getPlaceholderKey(canSendPlain) : undefined;\n\n return () => {\n // console.warn('[input] finishpeerchange start');\n\n chatInput.classList.remove('hide');\n goDownBtn.classList.toggle('is-broadcast', isBroadcast);\n goDownBtn.classList.remove('hide');\n\n\n if(this.goDownUnreadBadge) {\n this.setUnreadCount();\n }\n\n if(this.chat.type === 'pinned') {\n chatInput.classList.toggle('can-pin', canPinMessage);\n }/* else if(this.chat.type === 'chat') {\n } */\n\n if(forwardElements) {\n this.forwardWasDroppingAuthor = false;\n forwardElements.showCaption.checkboxField.setValueSilently(true);\n forwardElements.showSender.checkboxField.setValueSilently(true);\n }\n\n if(btnScheduled && ackedScheduledMids) {\n btnScheduled.classList.add('hide');\n callbackify(ackedScheduledMids.result, (mids) => {\n if(!middleware() || !mids) return;\n btnScheduled.classList.toggle('hide', !mids.length);\n });\n }\n\n if(this.newMessageWrapper) {\n this.updateOffset(null, false, true);\n }\n\n if(botCommandsToggle) {\n this.hasBotCommands = undefined;\n this.botCommands.toggle(true, undefined, true);\n this.updateBotCommandsToggle(true);\n botCommandsToggle.remove();\n if(isBot) {\n const result = ackedPeerFull.result;\n callbackify(result, (userFull) => {\n if(!middleware()) return;\n this.updateBotCommands(userFull as UserFull.userFull, !(result instanceof Promise));\n });\n }\n }\n\n previousSendAs?.destroy();\n setSendAsCallback?.();\n replyKeyboard?.setPeer(peerId);\n sendMenu?.setPeerId(peerId);\n\n if(this.messageInput) {\n this.updateMessageInput(canSend, canSendPlain, placeholderKey);\n this.messageInput.dataset.peerId = '' + peerId;\n\n if(filteredAttachMenuButtons && attachMenu) {\n filteredAttachMenuButtons.then((visible) => {\n if(!middleware()) {\n return;\n }\n\n attachMenu.toggleAttribute('disabled', !visible.length);\n attachMenu.classList.toggle('btn-disabled', !visible.length);\n });\n }\n }\n\n this.messageInputField?.onFakeInput(undefined, true);\n\n let haveSomethingInControl = false;\n if(this.pinnedControlBtn) {\n const good = this.chat.type === 'pinned';\n haveSomethingInControl ||= good;\n this.pinnedControlBtn.classList.toggle('hide', !good);\n this.pinnedControlBtn.replaceChildren(i18n(canPinMessage ? 'Chat.Input.UnpinAll' : 'Chat.Pinned.DontShow'));\n }\n\n {\n const good = this.chat.isForum && !this.chat.isForumTopic && this.chat.type === 'chat';\n haveSomethingInControl ||= good;\n this.replyInTopicOverlay.classList.toggle('hide', !good);\n }\n\n this.botStartBtn.classList.toggle('hide', haveSomethingInControl);\n\n // * testing\n // this.startParam = this.appPeersManager.isBot(peerId) ? '123' : undefined;\n\n this.startParam = startParam;\n\n this._center(neededFakeContainer, false);\n\n // console.warn('[input] finishpeerchange ends');\n };\n }\n\n private updateOffset(type: 'commands' | 'as', forwards: boolean, skipAnimation?: boolean, useRafs?: number) {\n if(type) {\n this.newMessageWrapper.dataset.offset = type;\n } else {\n delete this.newMessageWrapper.dataset.offset;\n }\n\n SetTransition({\n element: this.newMessageWrapper,\n className: 'has-offset',\n forwards,\n duration: skipAnimation ? 0 : 300,\n useRafs\n });\n }\n\n private updateBotCommands(userFull: UserFull.userFull, skipAnimation?: boolean) {\n this.hasBotCommands = !!userFull.bot_info?.commands?.length;\n this.updateBotCommandsToggle(skipAnimation);\n }\n\n private updateBotCommandsToggle(skipAnimation?: boolean) {\n const {botCommandsToggle, hasBotCommands} = this;\n\n const show = !!hasBotCommands && this.isInputEmpty();\n if(!hasBotCommands) {\n if(!botCommandsToggle.parentElement) {\n return;\n }\n\n botCommandsToggle.remove();\n }\n\n const forwards = show;\n const useRafs = botCommandsToggle.parentElement ? 0 : 2;\n\n if(!botCommandsToggle.parentElement) {\n this.newMessageWrapper.prepend(botCommandsToggle);\n }\n\n this.updateOffset('commands', forwards, skipAnimation, useRafs);\n }\n\n private async getPlaceholderKey(canSend?: boolean) {\n canSend ??= await this.chat.canSend('send_plain');\n const {peerId, threadId, isForum} = this.chat;\n let key: LangPackKey;\n if(!canSend) {\n key = 'Channel.Persmission.MessageBlock';\n } else if(threadId && !isForum) {\n key = 'Comment';\n } else if(await this.managers.appPeersManager.isBroadcast(peerId)) {\n key = 'ChannelBroadcast';\n } else if(\n (this.sendAsPeerId !== undefined && this.sendAsPeerId !== rootScope.myId) ||\n await this.managers.appMessagesManager.isAnonymousSending(peerId)\n ) {\n key = 'SendAnonymously';\n } else {\n key = 'Message';\n }\n\n return key;\n }\n\n private updateMessageInputPlaceholder(key: LangPackKey) {\n // console.warn('[input] update placeholder');\n const i = I18n.weakMap.get(this.messageInput) as I18n.IntlElement;\n if(!i) {\n return;\n }\n\n const oldKey = i.key;\n i.compareAndUpdate({key});\n\n return {oldKey, newKey: key};\n }\n\n private filterAttachMenuButtons() {\n if(!this.attachMenuButtons) return;\n return filterAsync(this.attachMenuButtons, (button) => {\n return button.verify ? button.verify() : true;\n });\n }\n\n public updateMessageInput(\n canSend: boolean,\n canSendPlain: boolean,\n placeholderKey: LangPackKey\n ) {\n const {chatInput, messageInput} = this;\n const isHidden = chatInput.classList.contains('is-hidden');\n const willBeHidden = !canSend;\n if(isHidden !== willBeHidden) {\n chatInput.classList.add('no-transition');\n chatInput.classList.toggle('is-hidden', !canSend);\n void chatInput.offsetLeft; // reflow\n chatInput.classList.remove('no-transition');\n }\n\n const isEditingAndLocked = canSend && !canSendPlain && this.restoreInputLock;\n\n !isEditingAndLocked && this.updateMessageInputPlaceholder(placeholderKey);\n\n if(isEditingAndLocked) {\n this.restoreInputLock = () => {\n this.updateMessageInputPlaceholder(placeholderKey);\n this.messageInput.contentEditable = 'false';\n };\n } else if(!canSend || !canSendPlain) {\n messageInput.contentEditable = 'false';\n\n if(!canSendPlain) {\n this.messageInputField.onFakeInput(undefined, true);\n }\n } else {\n this.restoreInputLock = undefined;\n messageInput.contentEditable = 'true';\n this.setDraft(undefined, false);\n\n if(!messageInput.innerHTML) {\n this.messageInputField.onFakeInput(undefined, true);\n }\n }\n\n this.updateSendBtn();\n }\n\n private attachMessageInputField() {\n const oldInputField = this.messageInputField;\n this.messageInputField = new InputFieldAnimated({\n placeholder: 'Message',\n name: 'message',\n withLinebreaks: true\n });\n\n this.messageInputField.input.tabIndex = -1;\n this.messageInputField.input.classList.replace('input-field-input', 'input-message-input');\n this.messageInputField.inputFake.classList.replace('input-field-input', 'input-message-input');\n this.messageInput = this.messageInputField.input;\n this.attachMessageInputListeners();\n\n if(IS_STICKY_INPUT_BUGGED) {\n fixSafariStickyInputFocusing(this.messageInput);\n }\n\n if(oldInputField) {\n oldInputField.input.replaceWith(this.messageInputField.input);\n oldInputField.inputFake.replaceWith(this.messageInputField.inputFake);\n } else {\n this.inputMessageContainer.append(this.messageInputField.input, this.messageInputField.inputFake);\n }\n }\n\n private attachMessageInputListeners() {\n this.listenerSetter.add(this.messageInput)('keydown', (e) => {\n const key = e.key;\n\n if(isSendShortcutPressed(e)) {\n cancelEvent(e);\n this.sendMessage();\n } else if(e.ctrlKey || e.metaKey) {\n this.handleMarkdownShortcut(e);\n } else if((key === 'PageUp' || key === 'PageDown') && !e.shiftKey) { // * fix pushing page to left (Chrome Windows)\n e.preventDefault();\n\n if(key === 'PageUp') {\n const range = document.createRange();\n const sel = window.getSelection();\n\n range.setStart(this.messageInput.childNodes[0] || this.messageInput, 0);\n range.collapse(true);\n\n sel.removeAllRanges();\n sel.addRange(range);\n } else {\n placeCaretAtEnd(this.messageInput);\n }\n }\n });\n\n attachClickEvent(this.messageInput, (e) => {\n if(!this.canSendPlain()) {\n toastNew({\n langPackKey: POSTING_NOT_ALLOWED_MAP['send_plain']\n });\n }\n }, {listenerSetter: this.listenerSetter});\n\n if(IS_TOUCH_SUPPORTED) {\n attachClickEvent(this.messageInput, (e) => {\n if(emoticonsDropdown.isActive()) {\n emoticonsDropdown.toggle(false);\n blurActiveElement();\n cancelEvent(e);\n // this.messageInput.focus();\n return;\n }\n\n this.appImManager.selectTab(APP_TABS.CHAT); // * set chat tab for album orientation\n // this.saveScroll();\n }, {listenerSetter: this.listenerSetter});\n\n /* this.listenerSetter.add(window)('resize', () => {\n this.restoreScroll();\n }); */\n\n /* if(isSafari) {\n this.listenerSetter.add(this.messageInput)('mousedown', () => {\n window.requestAnimationFrame(() => {\n window.requestAnimationFrame(() => {\n emoticonsDropdown.toggle(false);\n });\n });\n });\n } */\n }\n\n /* this.listenerSetter.add(this.messageInput)('beforeinput', (e: Event) => {\n // * validate due to manual formatting through browser's context menu\n const inputType = (e as InputEvent).inputType;\n //console.log('message beforeinput event', e);\n\n if(inputType.indexOf('format') === 0) {\n //console.log('message beforeinput format', e, inputType, this.messageInput.innerHTML);\n const markdownType = inputType.split('format')[1].toLowerCase() as MarkdownType;\n if(this.applyMarkdown(markdownType)) {\n cancelEvent(e); // * cancel legacy markdown event\n }\n }\n }); */\n this.listenerSetter.add(this.messageInput)('input', this.onMessageInput);\n this.listenerSetter.add(this.messageInput)('keyup', () => {\n this.checkAutocomplete();\n });\n\n this.listenerSetter.add(this.messageInput)('focusin', () => {\n if((this.chat.type === 'chat' || this.chat.type === 'discussion') &&\n this.chat.bubbles.scrollable.loadedAll.bottom) {\n this.managers.appMessagesManager.readAllHistory(this.chat.peerId, this.chat.threadId);\n }\n });\n }\n\n public canSendPlain() {\n return !(!this.messageInput.isContentEditable && !this.chatInput.classList.contains('is-hidden'));\n }\n\n private prepareDocumentExecute = () => {\n this.executedHistory.push(this.messageInput.innerHTML);\n return () => this.canUndoFromHTML = this.messageInput.innerHTML;\n };\n\n private undoRedo = (e: Event, type: 'undo' | 'redo', needHTML: string) => {\n cancelEvent(e); // cancel legacy event\n\n let html = this.messageInput.innerHTML;\n if(html && html !== needHTML) {\n this.lockRedo = true;\n\n let sameHTMLTimes = 0;\n do {\n document.execCommand(type, false, null);\n const currentHTML = this.messageInput.innerHTML;\n if(html === currentHTML) {\n if(++sameHTMLTimes > 2) { // * unlink, removeFormat (а может и нет, случай: заболдить подчёркнутый текст (выделить ровно его), попробовать отменить)\n break;\n }\n } else {\n sameHTMLTimes = 0;\n }\n\n html = currentHTML;\n } while(html !== needHTML);\n\n this.lockRedo = false;\n }\n };\n\n public applyMarkdown(type: MarkdownType, href?: string) {\n // const MONOSPACE_FONT = 'var(--font-monospace)';\n // const SPOILER_FONT = 'spoiler';\n const commandsMap: Partial<{[key in typeof type]: string | (() => void)}> = {\n // bold: 'Bold',\n // italic: 'Italic',\n // underline: 'Underline',\n // strikethrough: 'Strikethrough',\n // monospace: () => document.execCommand('fontName', false, MONOSPACE_FONT),\n link: href ? () => document.execCommand('createLink', false, href) : () => document.execCommand('unlink', false, null)\n // spoiler: () => document.execCommand('fontName', false, SPOILER_FONT)\n };\n\n const c = (type: MarkdownType) => {\n commandsMap[type] = () => {\n const k = (canCombine.includes(type) ? canCombine : [type]).filter((type) => hasMarkup[type]);\n if(!indexOfAndSplice(k, type)) {\n k.push(type);\n }\n\n if(!k.length) {\n return this.resetCurrentFontFormatting();\n } else {\n return document.execCommand('fontName', false, 'markup-' + k.join('-'));\n }\n };\n };\n\n const canCombine = ['bold', 'italic', 'underline', 'strikethrough', 'spoiler'] as (typeof type)[];\n canCombine.forEach((type) => {\n c(type);\n });\n\n c('monospace');\n\n if(!commandsMap[type]) {\n return false;\n }\n\n const command = commandsMap[type];\n\n // type = 'monospace';\n\n // const saveExecuted = this.prepareDocumentExecute();\n const executed: any[] = [];\n /**\n * * clear previous formatting, due to Telegram's inability to handle several entities\n */\n /* const checkForSingle = () => {\n const nodes = getSelectedNodes();\n //console.log('Using formatting:', commandsMap[type], nodes, this.executedHistory);\n\n const parents = [...new Set(nodes.map((node) => node.parentNode))];\n //const differentParents = !!nodes.find((node) => node.parentNode !== firstParent);\n const differentParents = parents.length > 1;\n\n let notSingle = false;\n if(differentParents) {\n notSingle = true;\n } else {\n const node = nodes[0];\n if(node && (node.parentNode as HTMLElement) !== this.messageInput && (node.parentNode.parentNode as HTMLElement) !== this.messageInput) {\n notSingle = true;\n }\n }\n\n if(notSingle) {\n //if(type === 'monospace') {\n executed.push(document.execCommand('styleWithCSS', false, 'true'));\n //}\n\n executed.push(document.execCommand('unlink', false, null));\n executed.push(document.execCommand('removeFormat', false, null));\n executed.push(typeof(command) === 'function' ? command() : document.execCommand(command, false, null));\n\n //if(type === 'monospace') {\n executed.push(document.execCommand('styleWithCSS', false, 'false'));\n //}\n }\n }; */\n\n // fix applying markdown when range starts from contenteditable=\"false\"\n let textNode: Text;\n // do {\n // // const {node, offset, selection} = getCaretPosNew(this.messageInput, true);\n // const selection = document.getSelection();\n // const range = selection.getRangeAt(0);\n // const {node, offset} = getCaretPosF(this.messageInput, range.startContainer, range.startOffset);\n // // const node = range.startContainer as ChildNode;\n // if(node?.textContent === BOM || (node as HTMLElement)?.isContentEditable === false) {\n // // selection.modify('extend', 'backward', 'character');\n // textNode = document.createTextNode(BOM);\n // (node.nodeType === node.ELEMENT_NODE ? node : node.parentElement).before(textNode);\n // range.setStart(textNode, 0);\n // }/* else {\n // break;\n // } */\n\n // break;\n // } while(true);\n\n const richInputHandler = RichInputHandler.getInstance();\n const restore = richInputHandler.prepareApplyingMarkdown();\n\n const listener = this.listenerSetter.add(this.messageInput)('input', cancelEvent, {capture: true, passive: false}) as any as Listener;\n\n executed.push(document.execCommand('styleWithCSS', false, 'true'));\n\n const hasMarkup = hasMarkupInSelection(Object.keys(commandsMap) as (typeof type)[]);\n\n // * monospace can't be combined with different types\n /* if(type === 'monospace' || type === 'spoiler') {\n // executed.push(document.execCommand('styleWithCSS', false, 'true'));\n\n const haveThisType = hasMarkup[type];\n // executed.push(document.execCommand('removeFormat', false, null));\n\n if(haveThisType) {\n executed.push(this.resetCurrentFontFormatting());\n } else {\n // if(type === 'monospace' || hasMarkup['monospace']) {\n // executed.push(this.resetCurrentFormatting());\n // }\n\n executed.push(typeof(command) === 'function' ? command() : document.execCommand(command, false, null));\n }\n } else */{\n if(hasMarkup['monospace'] && type === 'link') {\n executed.push(this.resetCurrentFormatting());\n }\n\n executed.push(typeof(command) === 'function' ? command() : document.execCommand(command, false, null));\n }\n\n executed.push(document.execCommand('styleWithCSS', false, 'false'));\n\n restore();\n\n // checkForSingle();\n // saveExecuted();\n this.appImManager.markupTooltip?.setActiveMarkupButton();\n\n if(textNode) {\n (textNode.parentElement === this.messageInput ? textNode : textNode.parentElement).remove();\n textNode.nodeValue = '';\n }\n\n this.listenerSetter.remove(listener);\n this.messageInputField.simulateInputEvent();\n\n return true;\n }\n\n private resetCurrentFormatting() {\n return document.execCommand('removeFormat', false, null);\n }\n\n private resetCurrentFontFormatting() {\n return document.execCommand('fontName', false, 'Roboto');\n }\n\n private handleMarkdownShortcut = (e: KeyboardEvent) => {\n // console.log('handleMarkdownShortcut', e);\n const formatKeys: {[key: string]: MarkdownType} = {\n 'KeyB': 'bold',\n 'KeyI': 'italic',\n 'KeyU': 'underline',\n 'KeyS': 'strikethrough',\n 'KeyM': 'monospace',\n 'KeyP': 'spoiler'\n };\n\n if(this.appImManager.markupTooltip) {\n formatKeys['KeyK'] = 'link';\n }\n\n const code = e.code;\n const applyMarkdown = formatKeys[code];\n\n const selection = document.getSelection();\n if(!isSelectionEmpty(selection) && applyMarkdown) {\n // * костыльчик\n if(code === 'KeyK') {\n this.appImManager.markupTooltip.showLinkEditor();\n } else {\n this.applyMarkdown(applyMarkdown);\n }\n\n cancelEvent(e); // cancel legacy event\n }\n\n // return;\n if(code === 'KeyZ') {\n let html = this.messageInput.innerHTML;\n\n if(e.shiftKey) {\n if(this.undoHistory.length) {\n this.executedHistory.push(html);\n html = this.undoHistory.pop();\n this.undoRedo(e, 'redo', html);\n html = this.messageInput.innerHTML;\n this.canRedoFromHTML = this.undoHistory.length ? html : '';\n this.canUndoFromHTML = html;\n }\n } else {\n // * подождём, когда пользователь сам восстановит поле до нужного состояния, которое стало сразу после saveExecuted\n if(this.executedHistory.length && (!this.canUndoFromHTML || html === this.canUndoFromHTML)) {\n this.undoHistory.push(html);\n html = this.executedHistory.pop();\n this.undoRedo(e, 'undo', html);\n\n // * поставим новое состояние чтобы снова подождать, если пользователь изменит что-то, и потом попробует откатить до предыдущего состояния\n this.canUndoFromHTML = this.canRedoFromHTML = this.messageInput.innerHTML;\n }\n }\n }\n };\n\n public onMessageInput = (e?: Event) => {\n // * validate due to manual formatting through browser's context menu\n /* const inputType = (e as InputEvent).inputType;\n console.log('message input event', e);\n if(inputType === 'formatBold') {\n console.log('message input format', this.messageInput.innerHTML);\n cancelEvent(e);\n }\n\n if(!isSelectionSingle()) {\n alert('not single');\n } */\n\n // console.log('messageInput input', this.messageInput.innerText);\n // const value = this.messageInput.innerText;\n const {value: richValue, entities: markdownEntities, caretPos} = getRichValueWithCaret(this.messageInputField.input);\n\n // const entities = parseEntities(value);\n const value = parseMarkdown(richValue, markdownEntities, true);\n const entities = mergeEntities(markdownEntities, parseEntities(value));\n\n // this.chat.log('messageInput entities', richValue, value, markdownEntities, caretPos);\n\n if(this.canRedoFromHTML && !this.lockRedo && this.messageInput.innerHTML !== this.canRedoFromHTML) {\n this.canRedoFromHTML = '';\n this.undoHistory.length = 0;\n }\n\n const urlEntities: Array<MessageEntity.messageEntityUrl | MessageEntity.messageEntityTextUrl> = (!this.editMessage?.media || this.editMessage.media._ === 'messageMediaWebPage') && entities.filter((e) => e._ === 'messageEntityUrl' || e._ === 'messageEntityTextUrl') as any;\n if(urlEntities.length) {\n for(const entity of urlEntities) {\n let url: string;\n if(entity._ === 'messageEntityTextUrl') {\n url = entity.url;\n } else {\n url = richValue.slice(entity.offset, entity.offset + entity.length);\n\n if(!(url.includes('http://') || url.includes('https://'))) {\n continue;\n }\n }\n\n if(this.lastUrl !== url) {\n this.lastUrl = url;\n const promise = this.getWebPagePromise = Promise.all([\n this.managers.appWebPagesManager.getWebPage(url),\n this.chat.canSend('embed_links')\n ]).then(([webpage, canEmbedLinks]) => {\n if(this.getWebPagePromise === promise) this.getWebPagePromise = undefined;\n if(this.lastUrl !== url) return;\n if(webpage?._ === 'webPage' && canEmbedLinks) {\n this.setTopInfo('webpage', () => {}, webpage.site_name || webpage.title || 'Webpage', webpage.description || webpage.url || '');\n delete this.noWebPage;\n this.willSendWebPage = webpage;\n } else if(this.willSendWebPage) {\n this.onHelperCancel();\n }\n });\n }\n\n break;\n }\n } else if(this.lastUrl) {\n this.lastUrl = '';\n delete this.noWebPage;\n this.willSendWebPage = null;\n\n if(this.helperType) {\n this.helperFunc();\n } else {\n this.clearHelper();\n }\n }\n\n const isEmpty = !richValue.trim();\n if(isEmpty) {\n if(this.lastTimeType) {\n this.managers.appMessagesManager.setTyping(this.chat.peerId, {_: 'sendMessageCancelAction'}, undefined, this.chat.threadId);\n }\n\n this.appImManager.markupTooltip?.hide();\n\n // * Chrome has a bug - it will preserve the formatting if the input with monospace text is cleared\n // * so have to reset formatting\n if(document.activeElement === this.messageInput && !IS_MOBILE) {\n setTimeout(() => {\n if(document.activeElement === this.messageInput) {\n this.messageInput.textContent = '1';\n placeCaretAtEnd(this.messageInput);\n this.messageInput.textContent = '';\n }\n }, 0);\n }\n } else {\n const time = Date.now();\n if((time - this.lastTimeType) >= 6000 && e?.isTrusted) {\n this.lastTimeType = time;\n this.managers.appMessagesManager.setTyping(this.chat.peerId, {_: 'sendMessageTypingAction'}, undefined, this.chat.threadId);\n }\n\n this.botCommands?.toggle(true);\n }\n\n if(this.botCommands) {\n this.updateBotCommandsToggle();\n }\n\n if(!this.editMsgId) {\n this.saveDraftDebounced();\n }\n\n this.checkAutocomplete(richValue, caretPos, entities);\n\n this.updateSendBtn();\n };\n\n public insertAtCaret(insertText: string, insertEntity?: MessageEntity, isHelper = true) {\n if(!this.canSendPlain()) {\n toastNew({\n langPackKey: POSTING_NOT_ALLOWED_MAP['send_plain']\n });\n return;\n }\n\n RichInputHandler.getInstance().makeFocused(this.messageInput);\n\n const {value: fullValue, caretPos, entities} = getRichValueWithCaret(this.messageInput);\n const pos = caretPos >= 0 ? caretPos : fullValue.length;\n const prefix = fullValue.substr(0, pos);\n const suffix = fullValue.substr(pos);\n\n const matches = isHelper ? prefix.match(ChatInput.AUTO_COMPLETE_REG_EXP) : null;\n\n const matchIndex = matches ? matches.index + (matches[0].length - matches[2].length) : prefix.length;\n const newPrefix = prefix.slice(0, matchIndex);\n const newValue = newPrefix + insertText + suffix;\n\n if(isHelper && caretPos !== -1) {\n const match = matches[2];\n // const {node, selection} = getCaretPosNew(this.messageInput);\n\n const selection = document.getSelection();\n // const range = document.createRange();\n let counter = 0;\n while(selection.toString() !== match) {\n if(++counter >= 10000) {\n throw new Error('lolwhat');\n }\n\n // for(let i = 0; i < match.length; ++i) {\n selection.modify('extend', 'backward', 'character');\n }\n }\n\n {\n // const fragment = wrapDraftText(insertText, {entities: insertEntity ? [insertEntity] : undefined, wrappingForPeerId: this.chat.peerId});\n insertRichTextAsHTML(this.messageInput, insertText, insertEntity ? [insertEntity] : undefined, this.chat.peerId);\n // const {node, offset} = getCaretPos(this.messageInput);\n // const fragmentLastChild = fragment.lastChild;\n // if(node?.nodeType === node.TEXT_NODE) {\n // const prefix = node.nodeValue.slice(0, offset);\n // const suffix = node.nodeValue.slice(offset);\n\n // const suffixNode = document.createTextNode(suffix);\n\n // node.nodeValue = prefix;\n // node.parentNode.insertBefore(suffixNode, node.nextSibling);\n // node.parentNode.insertBefore(fragment, suffixNode);\n\n // setCaretAt(fragmentLastChild.nextSibling);\n\n // this.messageInputField.simulateInputEvent();\n // }\n }\n return;\n\n // merge emojis\n const hadEntities = parseEntities(fullValue);\n mergeEntities(entities, hadEntities);\n\n // max for additional whitespace\n const insertLength = insertEntity ? Math.max(insertEntity.length, insertText.length) : insertText.length;\n const addEntities: MessageEntity[] = [];\n if(insertEntity) {\n addEntities.push(insertEntity);\n insertEntity.offset = matchIndex;\n }\n\n // add offset to entities next to emoji\n const diff = matches ? insertLength - matches[2].length : insertLength;\n entities.forEach((entity) => {\n if(entity.offset >= matchIndex) {\n entity.offset += diff;\n }\n });\n\n mergeEntities(entities, addEntities);\n\n if(/* caretPos !== -1 && caretPos !== fullValue.length */true) {\n const caretEntity: MessageEntity.messageEntityCaret = {\n _: 'messageEntityCaret',\n offset: matchIndex + insertLength,\n length: 0\n };\n\n let insertCaretAtIndex = 0;\n for(let length = entities.length; insertCaretAtIndex < length; ++insertCaretAtIndex) {\n const entity = entities[insertCaretAtIndex];\n if(entity.offset > caretEntity.offset) {\n break;\n }\n }\n\n entities.splice(insertCaretAtIndex, 0, caretEntity);\n }\n\n // const saveExecuted = this.prepareDocumentExecute();\n // can't exec .value here because it will instantly check for autocomplete\n const value = documentFragmentToHTML(wrapDraftText(newValue, {entities}));\n this.messageInputField.setValueSilently(value);\n\n const caret = this.messageInput.querySelector('.composer-sel');\n if(caret) {\n setCaretAt(caret);\n caret.remove();\n }\n\n // but it's needed to be checked only here\n this.onMessageInput();\n\n // saveExecuted();\n\n // document.execCommand('insertHTML', true, wrapEmojiText(emoji));\n }\n\n public onEmojiSelected = (emoji: ReturnType<typeof getEmojiFromElement>, autocomplete: boolean) => {\n const entity: MessageEntity = emoji.docId ? {\n _: 'messageEntityCustomEmoji',\n document_id: emoji.docId,\n length: emoji.emoji.length,\n offset: 0\n } : getEmojiEntityFromEmoji(emoji.emoji);\n this.insertAtCaret(emoji.emoji, entity, autocomplete);\n };\n\n private async checkAutocomplete(value?: string, caretPos?: number, entities?: MessageEntity[]) {\n // return;\n\n const hadValue = value !== undefined;\n if(!hadValue) {\n const r = getRichValueWithCaret(this.messageInputField.input, true, true);\n value = r.value;\n caretPos = r.caretPos;\n entities = r.entities;\n }\n\n if(caretPos === -1) {\n caretPos = value.length;\n }\n\n if(entities === undefined || !hadValue) {\n const _value = parseMarkdown(value, entities, true);\n entities = mergeEntities(entities, parseEntities(_value));\n }\n\n value = value.slice(0, caretPos);\n\n if(this.previousQuery === value) {\n return;\n }\n\n this.previousQuery = value;\n\n const matches = value.match(ChatInput.AUTO_COMPLETE_REG_EXP);\n let foundHelper: AutocompleteHelper;\n if(matches) {\n const entity = entities[0];\n\n let query = matches[2];\n const firstChar = query[0];\n\n if(this.stickersHelper &&\n rootScope.settings.stickers.suggest !== 'none' &&\n await this.chat.canSend('send_stickers') &&\n entity?._ === 'messageEntityEmoji' && entity.length === value.length && !entity.offset) {\n foundHelper = this.stickersHelper;\n this.stickersHelper.checkEmoticon(value);\n } else if(firstChar === '@') { // mentions\n const topMsgId = this.chat.threadId ? getServerMessageId(this.chat.threadId) : undefined;\n if(await this.mentionsHelper.checkQuery(query, this.chat.peerId.isUser() ? NULL_PEER_ID : this.chat.peerId, topMsgId)) {\n foundHelper = this.mentionsHelper;\n }\n } else if(!matches[1] && firstChar === '/') { // commands\n if(await this.commandsHelper.checkQuery(query, this.chat.peerId)) {\n foundHelper = this.commandsHelper;\n }\n } else if(rootScope.settings.emoji.suggest) { // emoji\n query = query.replace(/^\\s*/, '');\n if(!value.match(/^\\s*:(.+):\\s*$/) && !value.match(/:[;!@#$%^&*()-=|]/) && query) {\n foundHelper = this.emojiHelper;\n this.emojiHelper.checkQuery(query, firstChar);\n }\n }\n }\n\n let canSendInline: boolean;\n if(!foundHelper) {\n canSendInline = await this.chat.canSend('send_inline');\n }\n\n foundHelper = this.checkInlineAutocomplete(value, canSendInline, foundHelper);\n\n this.autocompleteHelperController.hideOtherHelpers(foundHelper);\n }\n\n private checkInlineAutocomplete(value: string, canSendInline: boolean, foundHelper?: AutocompleteHelper): AutocompleteHelper {\n let needPlaceholder = false;\n\n const setPreloaderShow = (show: boolean) => {\n if(!this.btnPreloader) {\n return;\n }\n\n if(show && !canSendInline) {\n show = false;\n }\n\n SetTransition({\n element: this.btnPreloader,\n className: 'show',\n forwards: show,\n duration: 400\n });\n };\n\n if(!foundHelper) {\n const inlineMatch = value.match(/^@([a-zA-Z\\\\d_]{3,32})\\s/);\n if(inlineMatch) {\n const username = inlineMatch[1];\n const query = value.slice(inlineMatch[0].length);\n needPlaceholder = inlineMatch[0].length === value.length;\n\n foundHelper = this.inlineHelper;\n\n if(!this.btnPreloader) {\n this.btnPreloader = this.createButtonIcon('none btn-preloader float show disable-hover', {noRipple: true});\n putPreloader(this.btnPreloader, true);\n this.inputMessageContainer.parentElement.insertBefore(this.btnPreloader, this.inputMessageContainer.nextSibling);\n } else {\n setPreloaderShow(true);\n }\n\n this.inlineHelper.checkQuery(this.chat.peerId, username, query, canSendInline).then(({user, renderPromise}) => {\n if(needPlaceholder && user.bot_inline_placeholder) {\n this.messageInput.dataset.inlinePlaceholder = user.bot_inline_placeholder;\n }\n\n renderPromise.then(() => {\n setPreloaderShow(false);\n });\n }).catch((err: ApiError) => {\n setPreloaderShow(false);\n });\n }\n }\n\n if(!needPlaceholder) {\n delete this.messageInput.dataset.inlinePlaceholder;\n }\n\n if(foundHelper !== this.inlineHelper) {\n setPreloaderShow(false);\n }\n\n return foundHelper;\n }\n\n private setRecording(value: boolean) {\n if(this.recording === value) {\n return;\n }\n\n SetTransition({\n element: this.chatInput,\n className: 'is-recording',\n forwards: value,\n duration: 200\n });\n this.recording = value;\n this.updateSendBtn();\n }\n\n private onBtnSendClick = async(e: Event) => {\n cancelEvent(e);\n\n if(!this.recorder || this.recording || !this.isInputEmpty() || this.forwarding || this.editMsgId) {\n if(this.recording) {\n if((Date.now() - this.recordStartTime) < RECORD_MIN_TIME) {\n this.onCancelRecordClick();\n } else {\n this.recorder.stop();\n }\n } else {\n this.sendMessage();\n }\n } else {\n const isAnyChat = this.chat.peerId.isAnyChat();\n const flag: ChatRights = 'send_voices';\n if(isAnyChat && !(await this.chat.canSend(flag))) {\n toastNew({langPackKey: POSTING_NOT_ALLOWED_MAP[flag]});\n return;\n }\n\n this.chatInput.classList.add('is-locked');\n blurActiveElement();\n\n let restricted = false;\n if(!isAnyChat) {\n const userFull = await this.managers.appProfileManager.getProfile(this.chat.peerId.toUserId());\n if(userFull?.pFlags.voice_messages_forbidden) {\n toastNew({\n langPackKey: 'Chat.SendVoice.PrivacyError',\n langPackArguments: [await wrapPeerTitle({peerId: this.chat.peerId})]\n });\n restricted = true;\n }\n }\n\n if(restricted) {\n this.chatInput.classList.remove('is-locked');\n return;\n }\n\n this.recorder.start().then(() => {\n this.releaseMediaPlayback = appMediaPlaybackController.setSingleMedia();\n this.recordCanceled = false;\n\n this.setRecording(true);\n opusDecodeController.setKeepAlive(true);\n\n const showDiscardPopup = () => {\n PopupElement.createPopup(PopupPeer, 'popup-cancel-record', {\n titleLangKey: 'DiscardVoiceMessageTitle',\n descriptionLangKey: 'DiscardVoiceMessageDescription',\n buttons: [{\n langKey: 'DiscardVoiceMessageAction',\n callback: () => {\n simulateClickEvent(this.btnCancelRecord);\n }\n }, {\n langKey: 'Continue',\n isCancel: true\n }]\n }).show();\n };\n\n this.recordingOverlayListener = this.listenerSetter.add(document.body)('mousedown', (e) => {\n if(!findUpClassName(e.target, 'chat-input') && !findUpClassName(e.target, 'popup-cancel-record')) {\n cancelEvent(e);\n showDiscardPopup();\n }\n }, {capture: true, passive: false}) as any;\n\n appNavigationController.pushItem(this.recordingNavigationItem = {\n type: 'voice',\n onPop: () => {\n setTimeout(() => {\n showDiscardPopup();\n }, 0);\n\n return false;\n }\n });\n\n this.recordStartTime = Date.now();\n\n const sourceNode: MediaStreamAudioSourceNode = this.recorder.sourceNode;\n const context = sourceNode.context;\n\n const analyser = context.createAnalyser();\n sourceNode.connect(analyser);\n // analyser.connect(context.destination);\n analyser.fftSize = 32;\n\n const frequencyData = new Uint8Array(analyser.frequencyBinCount);\n const max = frequencyData.length * 255;\n const min = 54 / 150;\n const r = () => {\n if(!this.recording) return;\n\n analyser.getByteFrequencyData(frequencyData);\n\n let sum = 0;\n frequencyData.forEach((value) => {\n sum += value;\n });\n\n const percents = Math.min(1, (sum / max) + min);\n // console.log('frequencyData', frequencyData, percents);\n\n this.recordRippleEl.style.transform = `scale(${percents})`;\n\n const diff = Date.now() - this.recordStartTime;\n const ms = diff % 1000;\n\n const formatted = toHHMMSS(diff / 1000) + ',' + ('00' + Math.round(ms / 10)).slice(-2);\n\n this.recordTimeEl.innerText = formatted;\n\n fastRaf(r);\n };\n\n r();\n }).catch((e: Error) => {\n switch(e.name as string) {\n case 'NotAllowedError': {\n toast('Please allow access to your microphone');\n break;\n }\n\n case 'NotReadableError': {\n toast(e.message);\n break;\n }\n\n default:\n console.error('Recorder start error:', e, e.name, e.message);\n toast(e.message);\n break;\n }\n\n this.setRecording(false);\n this.chatInput.classList.remove('is-locked');\n });\n }\n };\n\n public onHelperCancel = async(e?: Event, force?: boolean) => {\n if(e) {\n cancelEvent(e);\n }\n\n if(this.willSendWebPage) {\n const lastUrl = this.lastUrl;\n let needReturn = false;\n if(this.helperType) {\n // if(this.helperFunc) {\n await this.helperFunc();\n // }\n\n needReturn = true;\n }\n\n // * restore values\n this.lastUrl = lastUrl;\n this.noWebPage = true;\n this.willSendWebPage = null;\n\n if(needReturn) return;\n }\n\n if(this.helperType === 'edit' && !force) {\n const message = this.editMessage;\n const draft = this.getCurrentInputAsDraft(true);\n if(draft) {\n delete draft.pFlags.no_webpage;\n }\n // const value = parseMarkdown(this.messageInputField.value, []);\n // if(message.message !== value) {\n const originalDraft = {...message, _: 'draftMessage'} as DraftMessage.draftMessage;\n if(originalDraft.entities?.length) {\n const canPassEntitiesTypes = new Set(Object.values(MARKDOWN_ENTITIES));\n originalDraft.entities = originalDraft.entities.slice();\n forEachReverse(originalDraft.entities, (entity, idx, arr) => {\n if(!canPassEntitiesTypes.has(entity._)) {\n arr.splice(idx, 1);\n }\n });\n\n if(!originalDraft.entities.length) {\n delete originalDraft.entities;\n }\n }\n\n if(!draftsAreEqual(draft, originalDraft)) {\n PopupElement.createPopup(PopupPeer, 'discard-editing', {\n buttons: [{\n langKey: 'Alert.Confirm.Discard',\n callback: () => {\n this.onHelperCancel(undefined, true);\n }\n }],\n descriptionLangKey: 'Chat.Edit.Cancel.Text'\n }).show();\n\n return;\n }\n }\n\n this.clearHelper();\n this.updateSendBtn();\n };\n\n private onHelperClick = (e: Event) => {\n cancelEvent(e);\n\n if(!findUpClassName(e.target, 'reply')) return;\n if(this.helperType === 'forward') {\n const {forwardElements} = this;\n if(forwardElements && IS_TOUCH_SUPPORTED && !forwardElements.container.classList.contains('active')) {\n contextMenuController.openBtnMenu(forwardElements.container);\n }\n } else if(this.helperType === 'reply') {\n this.chat.setMessageId(this.replyToMsgId);\n } else if(this.helperType === 'edit') {\n this.chat.setMessageId(this.editMsgId);\n }\n };\n\n private changeForwardRecipient() {\n if(this.helperWaitingForward) return;\n this.helperWaitingForward = true;\n\n const forwarding = copy(this.forwarding);\n const helperFunc = this.helperFunc;\n this.clearHelper();\n this.updateSendBtn();\n let selected = false;\n const popup = PopupElement.createPopup(PopupForward, forwarding, () => {\n selected = true;\n });\n\n popup.addEventListener('close', () => {\n this.helperWaitingForward = false;\n\n if(!selected) {\n helperFunc();\n }\n });\n }\n\n public async clearInput(canSetDraft = true, fireEvent = true, clearValue = '') {\n if(document.activeElement === this.messageInput && IS_MOBILE_SAFARI) { // fix first char uppercase\n const i = document.createElement('input');\n document.body.append(i);\n fixSafariStickyInput(i);\n this.messageInputField.setValueSilently(clearValue);\n fixSafariStickyInput(this.messageInput);\n i.remove();\n } else {\n this.messageInputField.setValueSilently(clearValue);\n }\n\n if(IS_TOUCH_SUPPORTED) {\n // this.messageInput.innerText = '';\n } else {\n // this.attachMessageInputField();\n // this.messageInput.innerText = '';\n\n // clear executions\n this.canRedoFromHTML = '';\n this.undoHistory.length = 0;\n this.executedHistory.length = 0;\n this.canUndoFromHTML = '';\n }\n\n let set = false;\n if(canSetDraft) {\n set = await this.setDraft(undefined, false);\n }\n\n if(!set && fireEvent) {\n this.onMessageInput();\n }\n }\n\n public isInputEmpty() {\n return isInputEmpty(this.messageInput);\n }\n\n public updateSendBtn() {\n let icon: 'send' | 'record' | 'edit' | 'schedule';\n\n const isInputEmpty = this.isInputEmpty();\n\n if(this.editMsgId) icon = 'edit';\n else if(!this.recorder || this.recording || !isInputEmpty || this.forwarding) icon = this.chat.type === 'scheduled' ? 'schedule' : 'send';\n else icon = 'record';\n\n ['send', 'record', 'edit', 'schedule'].forEach((i) => {\n this.btnSend.classList.toggle(i, icon === i);\n });\n\n if(this.btnScheduled) {\n this.btnScheduled.classList.toggle('show', isInputEmpty && this.chat.type !== 'scheduled');\n }\n\n if(this.btnToggleReplyMarkup) {\n this.btnToggleReplyMarkup.classList.toggle('show', isInputEmpty && this.chat.type !== 'scheduled');\n }\n }\n\n private getValueAndEntities(input: HTMLElement) {\n const {entities: apiEntities, value} = getRichValueWithCaret(input, true, false);\n const myEntities = parseEntities(value);\n const totalEntities = mergeEntities(apiEntities, myEntities);\n\n return {value, totalEntities};\n }\n\n public onMessageSent(clearInput = true, clearReply?: boolean) {\n if(this.chat.type !== 'scheduled') {\n this.managers.appMessagesManager.readAllHistory(this.chat.peerId, this.chat.threadId, true);\n }\n\n this.scheduleDate = undefined;\n this.sendSilent = undefined;\n\n const {totalEntities} = this.getValueAndEntities(this.messageInput);\n let nextOffset = 0;\n const emojiEntities: (MessageEntity.messageEntityEmoji | MessageEntity.messageEntityCustomEmoji)[] = totalEntities.filter((entity) => {\n if(entity._ === 'messageEntityEmoji' || entity._ === 'messageEntityCustomEmoji') {\n const endOffset = entity.offset + entity.length;\n return endOffset <= nextOffset ? false : (nextOffset = endOffset, true);\n }\n\n return false;\n }) as any;\n emojiEntities.forEach((entity) => {\n const emoji: AppEmoji = entity._ === 'messageEntityEmoji' ? {emoji: emojiFromCodePoints(entity.unicode)} : {docId: entity.document_id, emoji: ''};\n this.managers.appEmojiManager.pushRecentEmoji(emoji);\n });\n\n if(clearInput) {\n this.lastUrl = '';\n delete this.noWebPage;\n this.willSendWebPage = null;\n this.clearInput();\n }\n\n if(clearReply || clearInput) {\n this.clearHelper();\n }\n\n this.updateSendBtn();\n }\n\n public sendMessage(force = false) {\n const {editMsgId, chat} = this;\n if(chat.type === 'scheduled' && !force && !editMsgId) {\n this.scheduleSending();\n return;\n }\n\n const {peerId} = chat;\n const {noWebPage} = this;\n const sendingParams = this.chat.getMessageSendingParams();\n\n const {value, entities} = getRichValueWithCaret(this.messageInputField.input, true, false);\n\n // return;\n if(editMsgId) {\n const message = this.editMessage;\n if(value.trim() || message.media) {\n this.managers.appMessagesManager.editMessage(message, value, {\n entities,\n noWebPage: noWebPage\n });\n\n this.onMessageSent();\n } else {\n PopupElement.createPopup(PopupDeleteMessages, peerId, [editMsgId], chat.type);\n\n return;\n }\n } else if(value.trim()) {\n this.managers.appMessagesManager.sendText(peerId, value, {\n entities,\n ...sendingParams,\n noWebPage: noWebPage,\n webPage: this.getWebPagePromise ? undefined : this.willSendWebPage,\n clearDraft: true\n });\n\n if(this.chat.type === 'scheduled') {\n this.onMessageSent(true);\n } else {\n this.onMessageSent(false, false);\n }\n // this.onMessageSent();\n }\n\n // * wait for sendText set messageId for invokeAfterMsg\n if(this.forwarding) {\n const forwarding = copy(this.forwarding);\n // setTimeout(() => {\n for(const fromPeerId in forwarding) {\n this.managers.appMessagesManager.forwardMessages(peerId, fromPeerId.toPeerId(), forwarding[fromPeerId], {\n ...sendingParams,\n dropAuthor: this.forwardElements && this.forwardElements.hideSender.checkboxField.checked,\n dropCaptions: this.isDroppingCaptions()\n }).catch(async(err: ApiError) => {\n if(err.type === 'VOICE_MESSAGES_FORBIDDEN') {\n toastNew({\n langPackKey: 'Chat.SendVoice.PrivacyError',\n langPackArguments: [await wrapPeerTitle({peerId})]\n });\n }\n });\n }\n\n if(!value) {\n this.onMessageSent();\n }\n // }, 0);\n }\n\n // this.onMessageSent();\n }\n\n public async sendMessageWithDocument(\n document: MyDocument | DocId,\n force = false,\n clearDraft = false,\n silent = false\n ) {\n document = await this.managers.appDocsManager.getDoc(document);\n\n const flag = document.type === 'sticker' ? 'send_stickers' : (document.type === 'gif' ? 'send_gifs' : 'send_media');\n if(this.chat.peerId.isAnyChat() && !(await this.chat.canSend(flag))) {\n toastNew({langPackKey: POSTING_NOT_ALLOWED_MAP[flag]});\n return false;\n }\n\n if(this.chat.type === 'scheduled' && !force) {\n this.scheduleSending(() => this.sendMessageWithDocument(document, true, clearDraft, silent));\n return false;\n }\n\n if(!document) {\n return false;\n }\n\n if(document.sticker && getStickerEffectThumb(document) && !rootScope.premium) {\n return false;\n }\n\n this.managers.appMessagesManager.sendFile(this.chat.peerId, {\n ...this.chat.getMessageSendingParams(),\n file: document,\n isMedia: true,\n clearDraft,\n silent\n });\n this.onMessageSent(clearDraft, true);\n\n if(document.type === 'sticker') {\n this.managers.appStickersManager.saveRecentSticker(document.id);\n }\n\n return true;\n }\n\n private canToggleHideAuthor() {\n const {forwardElements} = this;\n if(!forwardElements) return false;\n const hideCaptionCheckboxField = forwardElements.hideCaption.checkboxField;\n return !hideCaptionCheckboxField.checked ||\n findUpTag(hideCaptionCheckboxField.label, 'FORM').classList.contains('hide');\n }\n\n private isDroppingCaptions() {\n return !this.canToggleHideAuthor();\n }\n\n /* public sendSomething(callback: () => void, force = false) {\n if(this.chat.type === 'scheduled' && !force) {\n this.scheduleSending(() => this.sendSomething(callback, true));\n return false;\n }\n\n callback();\n this.onMessageSent(false, true);\n\n return true;\n } */\n\n public async initMessageEditing(mid: number) {\n const message = (await this.chat.getMessage(mid)) as Message.message;\n\n let input = wrapDraftText(message.message, {entities: message.totalEntities, wrappingForPeerId: this.chat.peerId});\n const f = async() => {\n let restoreInputLock: () => void;\n if(!this.messageInput.isContentEditable) {\n const placeholderKey = await this.getPlaceholderKey(true);\n const {contentEditable} = this.messageInput;\n this.messageInput.contentEditable = 'true';\n const {oldKey} = this.updateMessageInputPlaceholder(placeholderKey);\n\n restoreInputLock = () => {\n this.messageInput.contentEditable = contentEditable;\n this.updateMessageInputPlaceholder(oldKey);\n };\n }\n\n const replyFragment = await wrapMessageForReply({message, usingMids: [message.mid]});\n this.setTopInfo('edit', f, i18n('AccDescrEditing'), replyFragment, input, message);\n\n this.editMsgId = mid;\n this.editMessage = message;\n input = undefined;\n\n this.restoreInputLock = restoreInputLock;\n };\n f();\n }\n\n public initMessagesForward(fromPeerIdsMids: {[fromPeerId: PeerId]: number[]}) {\n const f = async() => {\n // const peerTitles: string[]\n const fromPeerIds = Object.keys(fromPeerIdsMids).map((fromPeerId) => fromPeerId.toPeerId());\n const smth: Set<string> = new Set();\n let length = 0, messagesWithCaptionsLength = 0;\n\n const p = fromPeerIds.map(async(fromPeerId) => {\n const mids = fromPeerIdsMids[fromPeerId];\n const promises = mids.map(async(mid) => {\n const message = (await this.managers.appMessagesManager.getMessageByPeer(fromPeerId, mid)) as Message.message;\n if(message.fwd_from?.from_name && !message.fromId && !message.fwdFromId) {\n smth.add('N' + message.fwd_from.from_name);\n } else {\n smth.add('P' + message.fromId);\n }\n\n if(message.media && message.message) {\n ++messagesWithCaptionsLength;\n }\n });\n\n await Promise.all(promises);\n\n length += mids.length;\n });\n\n await Promise.all(p);\n\n const onlyFirstName = smth.size > 2;\n const peerTitles = [...smth].map((smth) => {\n const type = smth[0];\n smth = smth.slice(1);\n if(type === 'P') {\n const peerId = smth.toPeerId();\n return peerId === rootScope.myId ? i18n('Chat.Accessory.Forward.You') : new PeerTitle({peerId, dialog: false, onlyFirstName}).element;\n } else {\n return onlyFirstName ? smth.split(' ')[0] : smth;\n }\n });\n\n const {forwardElements} = this;\n const form = findUpTag(forwardElements.showCaption.checkboxField.label, 'FORM');\n form.classList.toggle('hide', !messagesWithCaptionsLength);\n const hideCaption = forwardElements.hideCaption.checkboxField.checked;\n if(messagesWithCaptionsLength && hideCaption) {\n forwardElements.hideSender.checkboxField.setValueSilently(true);\n } else if(this.forwardWasDroppingAuthor !== undefined) {\n (this.forwardWasDroppingAuthor ? forwardElements.hideSender : forwardElements.showSender).checkboxField.setValueSilently(true);\n }\n\n const titleKey: LangPackKey = forwardElements.showSender.checkboxField.checked ? 'Chat.Accessory.Forward' : 'Chat.Accessory.Hidden';\n const title = i18n(titleKey, [length]);\n\n const senderTitles = document.createDocumentFragment();\n if(peerTitles.length < 3) {\n senderTitles.append(...join(peerTitles, false));\n } else {\n senderTitles.append(peerTitles[0], i18n('AndOther', [peerTitles.length - 1]));\n }\n\n let firstMessage: Message.message, usingFullAlbum: boolean;\n if(fromPeerIds.length === 1) {\n const fromPeerId = fromPeerIds[0];\n const mids = fromPeerIdsMids[fromPeerId];\n firstMessage = (await this.managers.appMessagesManager.getMessageByPeer(fromPeerId, mids[0])) as Message.message;\n\n usingFullAlbum = !!firstMessage.grouped_id;\n if(usingFullAlbum) {\n const albumMids = await this.managers.appMessagesManager.getMidsByMessage(firstMessage);\n if(albumMids.length !== length || albumMids.find((mid) => !mids.includes(mid))) {\n usingFullAlbum = false;\n }\n }\n }\n\n const subtitleFragment = document.createDocumentFragment();\n const delimiter = ': ';\n if(usingFullAlbum || length === 1) {\n const mids = fromPeerIdsMids[fromPeerIds[0]];\n const replyFragment = await wrapMessageForReply({message: firstMessage, usingMids: mids});\n subtitleFragment.append(\n senderTitles,\n delimiter,\n replyFragment\n );\n } else {\n subtitleFragment.append(\n i18n('Chat.Accessory.Forward.From'),\n delimiter,\n senderTitles\n );\n }\n\n const newReply = this.setTopInfo('forward', f, title, subtitleFragment);\n\n forwardElements.modifyArgs.forEach((b, idx) => {\n const text = b.textElement;\n const intl: I18n.IntlElement = I18n.weakMap.get(text) as any;\n intl.args = [idx < 2 ? fromPeerIds.length : messagesWithCaptionsLength];\n intl.update();\n });\n\n if(this.forwardHover) {\n this.forwardHover.attachButtonListener(newReply, this.listenerSetter);\n }\n\n this.forwarding = fromPeerIdsMids;\n };\n\n f();\n }\n\n public async initMessageReply(mid: number) {\n if(this.replyToMsgId === mid) {\n return;\n }\n\n let message = await this.chat.getMessage(mid);\n const f = () => {\n let peerTitleEl: HTMLElement;\n if(!message) { // load missing replying message\n peerTitleEl = i18n('Loading');\n\n this.managers.appMessagesManager.reloadMessages(this.chat.peerId, mid).then((_message) => {\n if(this.replyToMsgId !== mid) {\n return;\n }\n\n message = _message;\n if(!message) {\n this.clearHelper('reply');\n } else {\n f();\n }\n });\n } else {\n peerTitleEl = new PeerTitle({\n peerId: message.fromId,\n dialog: false\n }).element;\n }\n\n this.setTopInfo('reply', f, peerTitleEl, message && (message as Message.message).message, undefined, message);\n this.setReplyToMsgId(mid)\n };\n f();\n }\n\n public setReplyToMsgId(mid: number) {\n this.replyToMsgId = mid;\n this.center(true);\n }\n\n public clearHelper(type?: ChatInputHelperType) {\n if(this.helperType === 'edit' && type !== 'edit') {\n this.clearInput();\n }\n\n if(type) {\n this.lastUrl = '';\n delete this.noWebPage;\n this.willSendWebPage = null;\n }\n\n if(type !== 'reply') {\n this.setReplyToMsgId(undefined);\n this.forwarding = undefined;\n }\n\n this.editMsgId = this.editMessage = undefined;\n this.helperType = this.helperFunc = undefined;\n\n if(this.restoreInputLock) {\n this.restoreInputLock?.();\n this.restoreInputLock = undefined;\n }\n\n if(this.chat.container.classList.contains('is-helper-active')) {\n appNavigationController.removeByType('input-helper');\n this.chat.container.classList.remove('is-helper-active');\n this.t();\n }\n }\n\n private t() {\n const className = 'is-toggling-helper';\n SetTransition({\n element: this.chat.container,\n className,\n forwards: true,\n duration: 150,\n onTransitionEnd: () => {\n this.chat.container.classList.remove(className);\n }\n });\n }\n\n public setInputValue(value: Parameters<InputFieldAnimated['setValueSilently']>[0], clear = true, focus = true) {\n if(!value) value = '';\n\n if(clear) this.clearInput(false, false, value as string);\n else this.messageInputField.setValueSilently(value);\n\n fastRaf(() => {\n focus && placeCaretAtEnd(this.messageInput);\n this.onMessageInput();\n this.messageInput.scrollTop = this.messageInput.scrollHeight;\n });\n }\n\n public setTopInfo(\n type: ChatInputHelperType,\n callerFunc: () => void,\n title: Parameters<typeof wrapReply>[0] = '',\n subtitle: Parameters<typeof wrapReply>[1] = '',\n input?: Parameters<InputFieldAnimated['setValueSilently']>[0],\n message?: any\n ) {\n if(this.willSendWebPage && type === 'reply') {\n return;\n }\n\n if(type !== 'webpage') {\n this.clearHelper(type);\n this.helperType = type;\n this.helperFunc = callerFunc;\n }\n\n const replyParent = this.replyElements.container;\n const oldReply = replyParent.lastElementChild.previousElementSibling;\n const haveReply = oldReply.classList.contains('reply');\n\n this.replyElements.iconBtn.replaceWith(this.replyElements.iconBtn = this.createButtonIcon((type === 'webpage' ? 'link' : type) + ' active reply-icon', {noRipple: true}));\n const {container} = wrapReply(title, subtitle, this.chat.animationGroup, message);\n if(haveReply) {\n oldReply.replaceWith(container);\n } else {\n replyParent.insertBefore(container, replyParent.lastElementChild);\n }\n\n if(type === 'webpage') {\n container.style.cursor = 'default';\n }\n\n if(!this.chat.container.classList.contains('is-helper-active')) {\n this.chat.container.classList.add('is-helper-active');\n this.t();\n }\n\n /* const scroll = appImManager.scrollable;\n if(scroll.isScrolledDown && !scroll.scrollLocked && !appImManager.messagesQueuePromise && !appImManager.setPeerPromise) {\n scroll.scrollTo(scroll.scrollHeight, 'top', true, true, 200);\n } */\n\n if(!IS_MOBILE) {\n appNavigationController.pushItem({\n type: 'input-helper',\n onPop: () => {\n this.onHelperCancel();\n }\n });\n }\n\n if(input !== undefined) {\n this.setInputValue(input);\n }\n\n setTimeout(() => {\n this.updateSendBtn();\n }, 0);\n\n return container;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {DraftMessage} from '../../layer';\nimport mergeEntities from '../../lib/richTextProcessor/mergeEntities';\nimport parseEntities from '../../lib/richTextProcessor/parseEntities';\nimport wrapDraftText from '../../lib/richTextProcessor/wrapDraftText';\n\nexport default function wrapDraft(draft: DraftMessage.draftMessage, wrappingForPeerId: PeerId, loadPromises?: Promise<any>[]) {\n const myEntities = parseEntities(draft.message);\n const apiEntities = draft.entities || [];\n const totalEntities = mergeEntities(apiEntities.slice(), myEntities); // ! only in this order, otherwise bold and emoji formatting won't work\n\n return wrapDraftText(draft.message, {entities: totalEntities, wrappingForPeerId, loadPromises});\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport callbackify from '../../helpers/callbackify';\nimport formatNumber from '../../helpers/number/formatNumber';\nimport {Document, MessagePeerReaction, ReactionCount} from '../../layer';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getPeerId from '../../lib/appManagers/utils/peers/getPeerId';\nimport rootScope from '../../lib/rootScope';\nimport SetTransition from '../singleTransition';\nimport StackedAvatars from '../stackedAvatars';\nimport {Awaited} from '../../types';\nimport wrapSticker from '../wrappers/sticker';\nimport wrapCustomEmoji from '../wrappers/customEmoji';\nimport wrapStickerAnimation from '../wrappers/stickerAnimation';\nimport {makeMediaSize} from '../../helpers/mediaSize';\nimport RLottiePlayer from '../../lib/rlottie/rlottiePlayer';\nimport {fastRaf} from '../../helpers/schedulers';\nimport noop from '../../helpers/noop';\nimport {Middleware} from '../../helpers/middleware';\nimport liteMode from '../../helpers/liteMode';\n\nconst CLASS_NAME = 'reaction';\nconst TAG_NAME = CLASS_NAME + '-element';\nconst REACTION_INLINE_SIZE = 14;\nconst REACTION_BLOCK_SIZE = 22;\n\nexport const REACTION_DISPLAY_INLINE_COUNTER_AT = 2;\nexport const REACTION_DISPLAY_BLOCK_COUNTER_AT = 4;\n\nexport type ReactionLayoutType = 'block' | 'inline';\n\nexport default class ReactionElement extends HTMLElement {\n private type: ReactionLayoutType;\n private counter: HTMLElement;\n private stickerContainer: HTMLElement;\n private stackedAvatars: StackedAvatars;\n private canRenderAvatars: boolean;\n private _reactionCount: ReactionCount;\n private wrapStickerPromise: Awaited<ReturnType<typeof wrapSticker>>['render'];\n private managers: AppManagers;\n private middleware: Middleware;\n\n constructor() {\n super();\n this.classList.add(CLASS_NAME);\n this.managers = rootScope.managers;\n }\n\n public get reactionCount() {\n return this._reactionCount;\n }\n\n public set reactionCount(reactionCount: ReactionCount) {\n this._reactionCount = reactionCount;\n }\n\n public get count() {\n return this.reactionCount.count;\n }\n\n public init(type: ReactionLayoutType, middleware: Middleware) {\n this.type = type;\n this.classList.add(CLASS_NAME + '-' + type);\n this.middleware = middleware;\n }\n\n public setCanRenderAvatars(canRenderAvatars: boolean) {\n this.canRenderAvatars = canRenderAvatars;\n }\n\n public render(doNotRenderSticker?: boolean) {\n const hadStickerContainer = !!this.stickerContainer;\n if(!hadStickerContainer) {\n this.stickerContainer = document.createElement('div');\n this.stickerContainer.classList.add(CLASS_NAME + '-sticker');\n this.append(this.stickerContainer);\n }\n\n const reactionCount = this.reactionCount;\n if(!doNotRenderSticker && !hadStickerContainer) {\n const reaction = reactionCount.reaction;\n if(reaction._ === 'reactionEmoji') {\n const availableReaction = this.managers.appReactionsManager.getReaction(reaction.emoticon);\n callbackify(availableReaction, (availableReaction) => {\n if(!availableReaction.center_icon) {\n this.stickerContainer.classList.add('is-static');\n }\n\n if(availableReaction.pFlags.inactive) {\n this.classList.add('is-inactive');\n }\n\n this.renderDoc(availableReaction.center_icon ?? availableReaction.static_icon);\n });\n } else if(reaction._ === 'reactionCustomEmoji') {\n this.stickerContainer.classList.add('is-custom');\n const wrapped = wrapCustomEmoji({\n docIds: [reaction.document_id],\n customEmojiSize: makeMediaSize(REACTION_BLOCK_SIZE, REACTION_BLOCK_SIZE)\n });\n\n this.stickerContainer.append(wrapped);\n }\n }\n }\n\n private renderDoc(doc: Document.document) {\n const size = this.type === 'inline' ? REACTION_INLINE_SIZE : REACTION_BLOCK_SIZE;\n const wrapPromise = this.wrapStickerPromise = wrapSticker({\n div: this.stickerContainer,\n doc,\n width: size,\n height: size,\n static: true,\n managers: this.managers,\n middleware: this.middleware\n }).then(({render}) => render).finally(() => {\n if(this.wrapStickerPromise === wrapPromise) {\n this.wrapStickerPromise = undefined;\n }\n });\n }\n\n public renderCounter() {\n const reactionCount = this.reactionCount;\n const displayOn = this.type === 'inline' ? REACTION_DISPLAY_INLINE_COUNTER_AT : REACTION_DISPLAY_BLOCK_COUNTER_AT;\n if(reactionCount.count >= displayOn || (this.type === 'block' && !this.canRenderAvatars)) {\n if(!this.counter) {\n this.counter = document.createElement(this.type === 'inline' ? 'i' : 'span');\n this.counter.classList.add(CLASS_NAME + '-counter');\n }\n\n const formatted = formatNumber(reactionCount.count);\n if(this.counter.textContent !== formatted) {\n this.counter.textContent = formatted;\n }\n\n if(!this.counter.parentElement) {\n this.append(this.counter);\n }\n } else if(this.counter?.parentElement) {\n this.counter.remove();\n this.counter = undefined;\n }\n }\n\n public renderAvatars(recentReactions: MessagePeerReaction[]) {\n if(this.type === 'inline') {\n return;\n }\n\n if(this.reactionCount.count >= REACTION_DISPLAY_BLOCK_COUNTER_AT || !this.canRenderAvatars) {\n if(this.stackedAvatars) {\n this.stackedAvatars.container.remove();\n this.stackedAvatars = undefined;\n }\n\n return;\n }\n\n if(!this.stackedAvatars) {\n this.stackedAvatars = new StackedAvatars({\n avatarSize: 24\n });\n\n this.append(this.stackedAvatars.container);\n }\n\n this.stackedAvatars.render(recentReactions.map((reaction) => getPeerId(reaction.peer_id)));\n }\n\n public setIsChosen(isChosen = this.reactionCount.chosen_order !== undefined) {\n if(this.type === 'inline') return;\n const wasChosen = this.classList.contains('is-chosen') && !this.classList.contains('backwards');\n if(wasChosen !== isChosen) {\n SetTransition({\n element: this,\n className: 'is-chosen',\n forwards: isChosen,\n duration: this.isConnected ? 300 : 0\n });\n }\n }\n\n public fireAroundAnimation() {\n if(!liteMode.isAvailable('effects_reactions')) {\n return;\n }\n\n const reaction = this.reactionCount.reaction;\n if(reaction._ !== 'reactionEmoji') return;\n callbackify(this.managers.appReactionsManager.getReaction(reaction.emoticon), (availableReaction) => {\n const size = this.type === 'inline' ? REACTION_INLINE_SIZE + 14 : REACTION_BLOCK_SIZE + 18;\n const div = document.createElement('div');\n div.classList.add(CLASS_NAME + '-sticker-activate');\n\n Promise.all([\n wrapSticker({\n div: div,\n doc: availableReaction.center_icon,\n width: size,\n height: size,\n withThumb: false,\n needUpscale: true,\n play: false,\n skipRatio: 1,\n group: 'none',\n needFadeIn: false,\n managers: this.managers,\n middleware: this.middleware\n }).then(({render}) => render as Promise<RLottiePlayer>),\n\n wrapStickerAnimation({\n doc: availableReaction.around_animation,\n size: 80,\n target: this.stickerContainer,\n side: 'center',\n skipRatio: 1,\n play: false,\n managers: this.managers,\n middleware: this.middleware\n }).stickerPromise.catch(noop)\n ]).then(([iconPlayer, aroundPlayer]) => {\n const remove = () => {\n // if(!isInDOM(div)) return;\n iconPlayer.remove();\n div.remove();\n this.stickerContainer.classList.remove('has-animation');\n };\n\n if(!aroundPlayer) {\n remove();\n return;\n }\n\n const removeOnFrame = () => {\n // if(!isInDOM(div)) return;\n fastRaf(remove);\n };\n\n iconPlayer.addEventListener('enterFrame', (frameNo) => {\n if(frameNo === iconPlayer.maxFrame) {\n if(this.wrapStickerPromise) { // wait for fade in animation\n this.wrapStickerPromise.then(() => {\n setTimeout(removeOnFrame, 1e3);\n });\n } else {\n removeOnFrame();\n }\n }\n });\n\n iconPlayer.addEventListener('firstFrame', () => {\n this.stickerContainer.append(div);\n this.stickerContainer.classList.add('has-animation');\n iconPlayer.play();\n aroundPlayer.play();\n }, {once: true});\n });\n });\n }\n}\n\ncustomElements.define(TAG_NAME, ReactionElement);\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport forEachReverse from '../../helpers/array/forEachReverse';\nimport positionElementByIndex from '../../helpers/dom/positionElementByIndex';\nimport {Middleware, MiddlewareHelper} from '../../helpers/middleware';\nimport {Message, ReactionCount} from '../../layer';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport reactionsEqual from '../../lib/appManagers/utils/reactions/reactionsEqual';\nimport rootScope from '../../lib/rootScope';\nimport ReactionElement, {ReactionLayoutType, REACTION_DISPLAY_BLOCK_COUNTER_AT} from './reaction';\n\nconst CLASS_NAME = 'reactions';\nconst TAG_NAME = CLASS_NAME + '-element';\n\nconst REACTIONS_ELEMENTS: Map<string, Set<ReactionsElement>> = new Map();\nexport {REACTIONS_ELEMENTS};\n\nexport default class ReactionsElement extends HTMLElement {\n private message: Message.message;\n private key: string;\n private isPlaceholder: boolean;\n private type: ReactionLayoutType;\n private sorted: ReactionElement[];\n private onConnectCallback: () => void;\n private managers: AppManagers;\n private middleware: Middleware;\n private middlewareHelpers: Map<ReactionElement, MiddlewareHelper>;\n\n constructor() {\n super();\n this.classList.add(CLASS_NAME);\n this.sorted = [];\n this.middlewareHelpers = new Map();\n this.managers = rootScope.managers;\n }\n\n connectedCallback() {\n let set = REACTIONS_ELEMENTS.get(this.key);\n if(!set) {\n REACTIONS_ELEMENTS.set(this.key, set = new Set());\n }\n\n set.add(this);\n\n if(this.onConnectCallback && this.isConnected) {\n this.onConnectCallback();\n this.onConnectCallback = undefined;\n }\n }\n\n disconnectedCallback() {\n const set = REACTIONS_ELEMENTS.get(this.key);\n set.delete(this);\n if(!set.size) {\n REACTIONS_ELEMENTS.delete(this.key);\n }\n }\n\n public getReactionCount(reactionElement: ReactionElement) {\n return this.sorted[this.sorted.indexOf(reactionElement)].reactionCount;\n }\n\n public getMessage() {\n return this.message;\n }\n\n public init(\n message: Message.message,\n type: ReactionLayoutType,\n middleware: Middleware,\n isPlaceholder = this.isPlaceholder\n ) {\n if(this.key !== undefined) {\n this.disconnectedCallback();\n }\n\n if(this.middleware !== middleware) {\n middleware.onDestroy(() => {\n this.middlewareHelpers.clear();\n });\n }\n\n this.message = message;\n this.key = this.message.peerId + '_' + this.message.mid;\n this.middleware = middleware;\n this.isPlaceholder = isPlaceholder;\n\n if(this.type !== type) {\n this.type = type;\n this.classList.add(CLASS_NAME + '-' + type);\n }\n\n this.connectedCallback();\n }\n\n public changeMessage(message: Message.message) {\n return this.init(message, this.type, this.middleware);\n }\n\n public update(message: Message.message, changedResults?: ReactionCount[]) {\n this.message = message;\n this.render(changedResults);\n }\n\n public render(changedResults?: ReactionCount[]) {\n const reactions = this.message.reactions;\n const hasReactions = !!(reactions && reactions.results.length);\n this.classList.toggle('has-no-reactions', !hasReactions);\n if(!hasReactions && !this.sorted.length) return;\n\n const availableReactionsResult = this.managers.appReactionsManager.getAvailableReactions();\n // callbackify(availableReactionsResult, () => {\n const counts = hasReactions ? (\n reactions.results\n // availableReactionsResult instanceof Promise ?\n // reactions.results :\n // reactions.results.filter((reactionCount) => {\n // return this.managers.appReactionsManager.isReactionActive(reactionCount.reaction);\n // })\n ) : [];\n\n // if(this.message.peerId.isUser()) {\n // counts.sort((a, b) => (b.count - a.count) || ((b.chosen_order ?? 0) - (a.chosen_order ?? 0)));\n // } else {\n counts.sort((a, b) => (b.count - a.count) || ((a.chosen_order ?? 0) - (b.chosen_order ?? 0)));\n // }\n\n forEachReverse(this.sorted, (reactionElement, idx, arr) => {\n const reaction = reactionElement.reactionCount.reaction;\n const found = counts.some((reactionCount) => reactionsEqual(reactionCount.reaction, reaction));\n if(!found) {\n const middlewareHelper = this.middlewareHelpers.get(reactionElement);\n middlewareHelper.destroy();\n this.middlewareHelpers.delete(reactionElement);\n arr.splice(idx, 1);\n reactionElement.remove();\n }\n });\n\n const totalReactions = counts.reduce((acc, c) => acc + c.count, 0);\n const canRenderAvatars = reactions && (!!reactions.pFlags.can_see_list || this.message.peerId.isUser()) && totalReactions < REACTION_DISPLAY_BLOCK_COUNTER_AT;\n this.sorted = counts.map((reactionCount, idx) => {\n let reactionElement: ReactionElement = this.sorted.find((reactionElement) => reactionsEqual(reactionElement.reactionCount.reaction, reactionCount.reaction));\n if(!reactionElement) {\n const middlewareHelper = this.middleware.create();\n reactionElement = new ReactionElement();\n reactionElement.init(this.type, middlewareHelper.get());\n this.middlewareHelpers.set(reactionElement, middlewareHelper);\n }\n\n positionElementByIndex(reactionElement, this, idx);\n\n const recentReactions = reactions.recent_reactions ? reactions.recent_reactions.filter((reaction) => reactionsEqual(reaction.reaction, reactionCount.reaction)) : [];\n reactionElement.reactionCount = {...reactionCount};\n reactionElement.setCanRenderAvatars(canRenderAvatars);\n reactionElement.render(this.isPlaceholder);\n reactionElement.renderCounter();\n reactionElement.renderAvatars(recentReactions);\n reactionElement.setIsChosen();\n\n return reactionElement;\n });\n\n // this.sorted.forEach((reactionElement, idx) => {\n // /* if(this.type === 'block' && this.childElementCount !== this.sorted.length) { // because of appended time\n // idx += 1;\n // } */\n\n // positionElementByIndex(reactionElement, this, idx);\n // });\n\n if(!this.isPlaceholder && changedResults?.length) {\n if(this.isConnected) {\n this.handleChangedResults(changedResults);\n } else {\n this.onConnectCallback = () => {\n this.handleChangedResults(changedResults);\n };\n }\n }\n // });\n\n // ! тут вообще не должно быть этого кода, но пока он побудет тут\n if(!this.sorted.length && this.type === 'block') {\n const parentElement = this.parentElement;\n this.remove();\n\n if(parentElement.classList.contains('document-message') && !parentElement.childNodes.length) {\n parentElement.remove();\n return;\n }\n\n const timeSpan = this.querySelector('.time');\n if(timeSpan) {\n parentElement.append(timeSpan);\n }\n }\n }\n\n private handleChangedResults(changedResults: ReactionCount[]) {\n // ! temp\n if(this.message.peerId !== appImManager.chat.peerId) return;\n\n changedResults.forEach((reactionCount) => {\n const reactionElement = this.sorted.find((reactionElement) => reactionsEqual(reactionElement.reactionCount.reaction, reactionCount.reaction));\n reactionElement?.fireAroundAnimation();\n });\n }\n}\n\ncustomElements.define(TAG_NAME, ReactionsElement);\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport {Middleware} from '../../helpers/middleware';\nimport limitSymbols from '../../helpers/string/limitSymbols';\nimport {Document, Message, MessageMedia, Photo, WebPage, VideoSize} from '../../layer';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport choosePhotoSize from '../../lib/appManagers/utils/photos/choosePhotoSize';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport DivAndCaption from '../divAndCaption';\nimport wrapMessageForReply from '../wrappers/messageForReply';\nimport wrapPhoto from '../wrappers/photo';\nimport wrapSticker from '../wrappers/sticker';\nimport wrapVideo from '../wrappers/video';\nimport {AnimationItemGroup} from '../animationIntersector';\n\nconst MEDIA_SIZE = 32;\n\nexport async function wrapReplyDivAndCaption(options: {\n title: string | HTMLElement | DocumentFragment,\n titleEl: HTMLElement,\n subtitle: string | HTMLElement | DocumentFragment,\n subtitleEl: HTMLElement,\n message: Message.message | Message.messageService,\n mediaEl: HTMLElement,\n loadPromises?: Promise<any>[],\n animationGroup: AnimationItemGroup\n}) {\n let {title, titleEl, subtitle, subtitleEl, mediaEl, message, loadPromises, animationGroup} = options;\n if(title !== undefined) {\n if(typeof(title) === 'string') {\n title = limitSymbols(title, 140);\n title = wrapEmojiText(title);\n }\n\n replaceContent(titleEl, title);\n }\n\n if(!loadPromises) {\n loadPromises = [];\n }\n\n let messageMedia: MessageMedia | WebPage.webPage = (message as Message.message)?.media;\n let setMedia = false, isRound = false;\n const mediaChildren = mediaEl ? Array.from(mediaEl.children).slice() : [];\n let middleware: Middleware;\n if(messageMedia && mediaEl) {\n subtitleEl.textContent = '';\n subtitleEl.append(await wrapMessageForReply({message, animationGroup, withoutMediaType: true}));\n\n messageMedia = (messageMedia as MessageMedia.messageMediaWebPage).webpage as WebPage.webPage || messageMedia;\n const photo = (messageMedia as MessageMedia.messageMediaPhoto).photo as Photo.photo;\n const document = (messageMedia as MessageMedia.messageMediaDocument).document as Document.document;\n if(photo || (document && document.thumbs?.length)/* ['video', 'sticker', 'gif', 'round', 'photo', 'audio'].indexOf(document.type) !== -1) */) {\n middleware = appImManager.chat.bubbles.getMiddleware();\n const lazyLoadQueue = appImManager.chat.bubbles.lazyLoadQueue;\n\n if(document?.type === 'sticker') {\n await wrapSticker({\n doc: document,\n div: mediaEl,\n lazyLoadQueue,\n group: animationGroup,\n // onlyThumb: document.sticker === 2,\n width: MEDIA_SIZE,\n height: MEDIA_SIZE,\n middleware,\n loadPromises\n });\n setMedia = true;\n } else if(document?.type === 'gif' && document.video_thumbs) {\n setMedia = true;\n await wrapVideo({\n doc: document,\n container: mediaEl,\n boxWidth: MEDIA_SIZE,\n boxHeight: MEDIA_SIZE,\n lazyLoadQueue,\n noPlayButton: true,\n noInfo: true,\n middleware,\n loadPromises,\n withoutPreloader: true,\n videoSize: document.video_thumbs[0] as Extract<VideoSize, VideoSize.videoSize>,\n group: animationGroup\n });\n } else {\n const m = photo || document;\n isRound = document?.type === 'round';\n\n try {\n await wrapPhoto({\n photo: m,\n container: mediaEl,\n boxWidth: MEDIA_SIZE,\n boxHeight: MEDIA_SIZE,\n size: choosePhotoSize(m, MEDIA_SIZE, MEDIA_SIZE),\n middleware,\n lazyLoadQueue,\n noBlur: true,\n withoutPreloader: true,\n loadPromises\n });\n setMedia = true;\n } catch(err) {\n\n }\n }\n }\n } else {\n if(message) {\n subtitleEl.textContent = '';\n subtitleEl.append(await wrapMessageForReply({message}));\n } else {\n if(typeof(subtitle) === 'string') {\n subtitle = limitSymbols(subtitle, 140);\n subtitle = wrapEmojiText(subtitle);\n }\n\n replaceContent(subtitleEl, subtitle || '');\n }\n }\n\n Promise.all(loadPromises).then(() => {\n if(middleware && !middleware()) return;\n mediaChildren.forEach((child) => child.remove());\n\n if(mediaEl) {\n mediaEl.classList.toggle('is-round', isRound);\n }\n });\n\n return setMedia;\n}\n\nexport default class ReplyContainer extends DivAndCaption<(title: string | HTMLElement | DocumentFragment, subtitle: string | HTMLElement | DocumentFragment, message?: any) => Promise<void>> {\n private mediaEl: HTMLElement;\n\n constructor(protected className: string, protected animationGroup: AnimationItemGroup) {\n super(className, async(title, subtitle = '', message?) => {\n if(!this.mediaEl) {\n this.mediaEl = document.createElement('div');\n this.mediaEl.classList.add(this.className + '-media');\n }\n\n const isMediaSet = await wrapReplyDivAndCaption({\n title,\n titleEl: this.title,\n subtitle,\n subtitleEl: this.subtitle,\n mediaEl: this.mediaEl,\n message,\n animationGroup\n });\n\n this.container.classList.toggle('is-media', isMediaSet);\n if(isMediaSet) {\n this.content.prepend(this.mediaEl);\n } else {\n this.mediaEl.remove();\n }\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {AppMessagesManager, MessagesStorageKey} from '../../lib/appManagers/appMessagesManager';\nimport type ChatBubbles from './bubbles';\nimport type ChatInput from './input';\nimport type Chat from './chat';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport Button from '../button';\nimport ButtonIcon from '../buttonIcon';\nimport CheckboxField from '../checkboxField';\nimport PopupDeleteMessages from '../popups/deleteMessages';\nimport PopupForward from '../popups/forward';\nimport SetTransition from '../singleTransition';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport PopupSendNow from '../popups/sendNow';\nimport appNavigationController, {NavigationItem} from '../appNavigationController';\nimport {IS_MOBILE_SAFARI} from '../../environment/userAgent';\nimport I18n, {i18n, _i18n} from '../../lib/langPack';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport blurActiveElement from '../../helpers/dom/blurActiveElement';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport cancelSelection from '../../helpers/dom/cancelSelection';\nimport getSelectedText from '../../helpers/dom/getSelectedText';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport AppSearchSuper from '../appSearchSuper.';\nimport isInDOM from '../../helpers/dom/isInDOM';\nimport {randomLong} from '../../helpers/random';\nimport {attachClickEvent, AttachClickOptions} from '../../helpers/dom/clickEvent';\nimport findUpAsChild from '../../helpers/dom/findUpAsChild';\nimport EventListenerBase from '../../helpers/eventListenerBase';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport {attachContextMenuListener} from '../../helpers/dom/attachContextMenuListener';\nimport filterUnique from '../../helpers/array/filterUnique';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport {Message} from '../../layer';\nimport PopupElement from '../popups';\n\nconst accumulateMapSet = (map: Map<any, Set<number>>) => {\n return [...map.values()].reduce((acc, v) => acc + v.size, 0);\n};\n\n// const MIN_CLICK_MOVE = 32; // minimum bubble height\n\nclass AppSelection extends EventListenerBase<{\n toggle: (isSelecting: boolean) => void\n}> {\n public selectedMids: Map<PeerId, Set<number>> = new Map();\n public isSelecting = false;\n\n public selectedText: string;\n\n protected listenerSetter: ListenerSetter;\n protected isScheduled: boolean;\n protected listenElement: HTMLElement;\n\n protected onToggleSelection: (forwards: boolean, animate: boolean) => void | Promise<void>;\n protected onUpdateContainer: (cantForward: boolean, cantDelete: boolean, cantSend: boolean) => void;\n protected onCancelSelection: () => void;\n protected toggleByMid: (peerId: PeerId, mid: number) => void;\n protected toggleByElement: (bubble: HTMLElement) => void;\n\n protected navigationType: NavigationItem['type'];\n\n protected getElementFromTarget: (target: HTMLElement) => HTMLElement;\n protected verifyTarget: (e: MouseEvent, target: HTMLElement) => boolean;\n protected verifyMouseMoveTarget: (e: MouseEvent, element: HTMLElement, selecting: boolean) => boolean;\n protected verifyTouchLongPress: () => boolean;\n protected targetLookupClassName: string;\n protected lookupBetweenParentClassName: string;\n protected lookupBetweenElementsQuery: string;\n\n protected doNotAnimate: boolean;\n protected managers: AppManagers;\n\n constructor(options: {\n managers: AppManagers,\n getElementFromTarget: AppSelection['getElementFromTarget'],\n verifyTarget?: AppSelection['verifyTarget'],\n verifyMouseMoveTarget?: AppSelection['verifyMouseMoveTarget'],\n verifyTouchLongPress?: AppSelection['verifyTouchLongPress'],\n targetLookupClassName: string,\n lookupBetweenParentClassName: string,\n lookupBetweenElementsQuery: string,\n isScheduled?: AppSelection['isScheduled']\n }) {\n super(false);\n\n safeAssign(this, options);\n\n this.navigationType = 'multiselect-' + randomLong() as any;\n }\n\n public attachListeners(listenElement: HTMLElement, listenerSetter: ListenerSetter) {\n if(this.listenElement) {\n this.listenerSetter.removeAll();\n }\n\n this.listenElement = listenElement;\n this.listenerSetter = listenerSetter;\n\n if(!listenElement) {\n return;\n }\n\n if(IS_TOUCH_SUPPORTED) {\n listenerSetter.add(listenElement)('touchend', () => {\n if(!this.isSelecting) return;\n this.selectedText = getSelectedText();\n });\n\n attachContextMenuListener({\n element: listenElement,\n callback: (e) => {\n if(this.isSelecting || (this.verifyTouchLongPress && !this.verifyTouchLongPress())) return;\n\n // * these two lines will fix instant text selection on iOS Safari\n document.body.classList.add('no-select'); // * need no-select on body because chat-input transforms in channels\n listenElement.addEventListener('touchend', (e) => {\n cancelEvent(e); // ! this one will fix propagation to document loader button, etc\n document.body.classList.remove('no-select');\n\n // this.chat.bubbles.onBubblesClick(e);\n }, {once: true, capture: true});\n\n cancelSelection();\n // cancelEvent(e as any);\n const element = this.getElementFromTarget(e.target as HTMLElement);\n if(element) {\n this.toggleByElement(element);\n }\n },\n listenerSetter\n });\n\n return;\n }\n\n listenerSetter.add(listenElement)('mousedown', this.onMouseDown);\n }\n\n private onMouseDown = (e: MouseEvent) => {\n // console.log('selection mousedown', e);\n const element = findUpClassName(e.target, this.targetLookupClassName);\n if(e.button !== 0) {\n return;\n }\n\n if(this.verifyTarget && !this.verifyTarget(e, element)) {\n return;\n }\n\n const seen: AppSelection['selectedMids'] = new Map();\n let selecting: boolean;\n\n /* let good = false;\n const {x, y} = e; */\n\n /* const bubbles = appImManager.bubbles;\n for(const mid in bubbles) {\n const bubble = bubbles[mid];\n bubble.addEventListener('mouseover', () => {\n console.log('mouseover');\n }, {once: true});\n } */\n\n let firstTarget = element;\n\n const processElement = (element: HTMLElement, checkBetween = true) => {\n const mid = +element.dataset.mid;\n if(!mid || !element.dataset.peerId) return;\n const peerId = element.dataset.peerId.toPeerId();\n\n if(!isInDOM(firstTarget)) {\n firstTarget = element;\n }\n\n let seenSet = seen.get(peerId);\n if(!seenSet) {\n seen.set(peerId, seenSet = new Set());\n }\n\n if(seenSet.has(mid)) {\n return;\n }\n\n const isSelected = this.isMidSelected(peerId, mid);\n if(selecting === undefined) {\n // bubblesContainer.classList.add('no-select');\n selecting = !isSelected;\n }\n\n seenSet.add(mid);\n\n if((selecting && !isSelected) || (!selecting && isSelected)) {\n const seenLength = accumulateMapSet(seen);\n if(this.toggleByElement && checkBetween) {\n if(seenLength < 2) {\n if(findUpAsChild(element, firstTarget)) {\n firstTarget = element;\n }\n }\n\n const elementsBetween = this.getElementsBetween(firstTarget, element);\n // console.log(elementsBetween);\n if(elementsBetween.length) {\n elementsBetween.forEach((element) => {\n processElement(element, false);\n });\n }\n }\n\n if(!this.selectedMids.size) {\n if(seenLength === 2 && this.toggleByMid) {\n for(const [peerId, mids] of seen) {\n for(const mid of mids) {\n this.toggleByMid(peerId, mid);\n }\n }\n }\n } else if(this.toggleByElement) {\n this.toggleByElement(element);\n }\n }\n };\n\n // const foundTargets: Map<HTMLElement, true> = new Map();\n let canceledSelection = false;\n const onMouseMove = (e: MouseEvent) => {\n if(!canceledSelection) {\n cancelSelection();\n canceledSelection = true;\n }\n /* if(!good) {\n if(Math.abs(e.x - x) > MIN_CLICK_MOVE || Math.abs(e.y - y) > MIN_CLICK_MOVE) {\n good = true;\n } else {\n return;\n }\n } */\n\n /* if(foundTargets.has(e.target as HTMLElement)) return;\n foundTargets.set(e.target as HTMLElement, true); */\n const element = this.getElementFromTarget(e.target as HTMLElement);\n if(!element) {\n // console.error('found no bubble', e);\n return;\n }\n\n if(this.verifyMouseMoveTarget && !this.verifyMouseMoveTarget(e, element, selecting)) {\n this.listenerSetter.removeManual(this.listenElement, 'mousemove', onMouseMove);\n this.listenerSetter.removeManual(document, 'mouseup', onMouseUp, documentListenerOptions);\n return;\n }\n\n processElement(element);\n };\n\n const onMouseUp = (e: MouseEvent) => {\n if(seen.size) {\n attachClickEvent(window, cancelEvent, {capture: true, once: true, passive: false});\n }\n\n this.listenerSetter.removeManual(this.listenElement, 'mousemove', onMouseMove);\n // bubblesContainer.classList.remove('no-select');\n\n // ! CANCEL USER SELECTION !\n cancelSelection();\n };\n\n const documentListenerOptions = {once: true};\n this.listenerSetter.add(this.listenElement)('mousemove', onMouseMove);\n this.listenerSetter.add(document)('mouseup', onMouseUp, documentListenerOptions);\n };\n\n private getElementsBetween = (first: HTMLElement, last: HTMLElement) => {\n if(first === last) {\n return [];\n }\n\n const firstRect = first.getBoundingClientRect();\n const lastRect = last.getBoundingClientRect();\n const difference = (firstRect.top - lastRect.top) || (firstRect.left - lastRect.left);\n const isHigher = difference < 0;\n\n const parent = findUpClassName(first, this.lookupBetweenParentClassName);\n if(!parent) {\n return [];\n }\n\n const elements = Array.from(parent.querySelectorAll(this.lookupBetweenElementsQuery)) as HTMLElement[];\n let firstIndex = elements.indexOf(first);\n let lastIndex = elements.indexOf(last);\n\n if(!isHigher) {\n [lastIndex, firstIndex] = [firstIndex, lastIndex];\n }\n\n const slice = elements.slice(firstIndex + 1, lastIndex);\n\n // console.log('getElementsBetween', first, last, slice, firstIndex, lastIndex, isHigher);\n\n return slice;\n };\n\n protected isElementShouldBeSelected(element: HTMLElement) {\n return this.isMidSelected(element.dataset.peerId.toPeerId(), +element.dataset.mid);\n }\n\n protected appendCheckbox(element: HTMLElement, checkboxField: CheckboxField) {\n element.prepend(checkboxField.label);\n }\n\n public toggleElementCheckbox(element: HTMLElement, show: boolean) {\n const hasCheckbox = !!this.getCheckboxInputFromElement(element);\n if(show) {\n if(hasCheckbox) {\n return false;\n }\n\n const checkboxField = new CheckboxField({\n name: element.dataset.mid,\n round: true\n });\n\n // * if it is a render of new message\n if(this.isSelecting) { // ! avoid breaking animation on start\n if(this.isElementShouldBeSelected(element)) {\n checkboxField.input.checked = true;\n element.classList.add('is-selected');\n }\n }\n\n this.appendCheckbox(element, checkboxField);\n } else if(hasCheckbox) {\n this.getCheckboxInputFromElement(element).parentElement.remove();\n SetTransition({\n element,\n className: 'is-selected',\n forwards: false,\n duration: 200\n });\n }\n\n return true;\n }\n\n protected getCheckboxInputFromElement(element: HTMLElement): HTMLInputElement {\n return element.firstElementChild?.tagName === 'LABEL' &&\n element.firstElementChild.firstElementChild as HTMLInputElement;\n }\n\n protected async updateContainer(forceSelection = false) {\n const size = this.selectedMids.size;\n if(!size && !forceSelection) return;\n\n let cantForward = !size,\n cantDelete = !size;\n const cantSend = !size;\n for(const [peerId, mids] of this.selectedMids) {\n const storageKey = this.getStorageKey(peerId);\n const r = await this.managers.appMessagesManager.cantForwardDeleteMids(storageKey, Array.from(mids));\n cantForward = r.cantForward;\n cantDelete = r.cantDelete;\n\n if(cantForward && cantDelete) break;\n }\n\n this.onUpdateContainer?.(cantForward, cantDelete, cantSend);\n }\n\n private getStorageKey(peerId: PeerId): MessagesStorageKey {\n return `${peerId}_${this.isScheduled ? 'scheduled' : 'history'}`;\n }\n\n public getSelectedMessages() {\n const selectedMessagesPromises: Promise<Message.message | Message.messageService>[] = [];\n this.selectedMids.forEach((mids, peerId) => {\n const storageKey = this.getStorageKey(peerId);\n const p = Array.from(mids).map((mid) => this.managers.appMessagesManager.getMessageFromStorage(storageKey, mid));\n selectedMessagesPromises.push(...p);\n });\n return Promise.all(selectedMessagesPromises);\n }\n\n public toggleSelection(toggleCheckboxes = true, forceSelection = false) {\n const wasSelecting = this.isSelecting;\n const size = this.selectedMids.size;\n this.isSelecting = !!size || forceSelection;\n\n if(wasSelecting === this.isSelecting) return false;\n\n this.dispatchEvent('toggle', this.isSelecting);\n\n // const bubblesContainer = this.bubbles.bubblesContainer;\n // bubblesContainer.classList.toggle('is-selecting', !!size);\n\n /* if(bubblesContainer.classList.contains('is-chat-input-hidden')) {\n const scrollable = this.appImManager.scrollable;\n if(scrollable.isScrolledDown) {\n scrollable.scrollTo(scrollable.scrollHeight, 'top', true, true, 200);\n }\n } */\n\n if(!IS_TOUCH_SUPPORTED) {\n this.listenElement.classList.toggle('no-select', this.isSelecting);\n\n if(wasSelecting) {\n // ! CANCEL USER SELECTION !\n cancelSelection();\n }\n }/* else {\n if(!wasSelecting) {\n bubblesContainer.classList.add('no-select');\n setTimeout(() => {\n cancelSelection();\n bubblesContainer.classList.remove('no-select');\n cancelSelection();\n }, 100);\n }\n } */\n\n blurActiveElement();\n\n const forwards = !!size || forceSelection;\n const toggleResult = this.onToggleSelection?.(forwards, !this.doNotAnimate);\n\n if(!IS_MOBILE_SAFARI) {\n if(forwards) {\n appNavigationController.pushItem({\n type: this.navigationType,\n onPop: () => {\n this.cancelSelection();\n }\n });\n } else {\n appNavigationController.removeByType(this.navigationType);\n }\n }\n\n if(forceSelection) {\n (toggleResult || Promise.resolve()).then(() => this.updateContainer(forceSelection));\n }\n\n return true;\n }\n\n public cancelSelection = async(doNotAnimate?: boolean) => {\n if(doNotAnimate) this.doNotAnimate = true;\n this.onCancelSelection && await this.onCancelSelection();\n this.selectedMids.clear();\n this.toggleSelection();\n cancelSelection();\n if(doNotAnimate) this.doNotAnimate = undefined;\n };\n\n public cleanup() {\n this.doNotAnimate = true;\n this.selectedMids.clear();\n this.toggleSelection(false);\n this.doNotAnimate = undefined;\n }\n\n protected updateElementSelection(element: HTMLElement, isSelected: boolean) {\n this.toggleElementCheckbox(element, true);\n const input = this.getCheckboxInputFromElement(element);\n input.checked = isSelected;\n\n this.toggleSelection();\n this.updateContainer();\n SetTransition({\n element,\n className: 'is-selected',\n forwards: isSelected,\n duration: 200\n });\n }\n\n public isMidSelected(peerId: PeerId, mid: number) {\n const set = this.selectedMids.get(peerId);\n return !!set?.has(mid);\n }\n\n public length() {\n return accumulateMapSet(this.selectedMids);\n }\n\n protected toggleMid(peerId: PeerId, mid: number, unselect?: boolean) {\n let set = this.selectedMids.get(peerId);\n if(unselect || (unselect === undefined && set?.has(mid))) {\n if(set) {\n set.delete(mid);\n\n if(!set.size) {\n this.selectedMids.delete(peerId);\n }\n }\n } else {\n // const diff = rootScope.config.forwarded_count_max - this.length() - 1;\n // if(diff < 0) {\n // toast(I18n.format('Chat.Selection.LimitToast', true));\n // return false;\n // /* const it = this.selectedMids.values();\n // do {\n // const mid = it.next().value;\n // const mounted = this.appImManager.getMountedBubble(mid);\n // if(mounted) {\n // this.toggleByBubble(mounted.bubble);\n // } else {\n // const mids = this.appMessagesManager.getMidsByMid(mid);\n // for(const mid of mids) {\n // this.selectedMids.delete(mid);\n // }\n // }\n // } while(this.selectedMids.size > MAX_SELECTION_LENGTH); */\n // }\n\n if(!set) {\n set = new Set();\n this.selectedMids.set(peerId, set);\n }\n\n set.add(mid);\n }\n\n return true;\n }\n\n /**\n * ! Call this method only to handle deleted messages\n */\n public deleteSelectedMids(peerId: PeerId, mids: number[]) {\n const set = this.selectedMids.get(peerId);\n if(!set) {\n return;\n }\n\n mids.forEach((mid) => {\n set.delete(mid);\n });\n\n if(!set.size) {\n this.selectedMids.delete(peerId);\n }\n\n this.updateContainer();\n this.toggleSelection();\n }\n}\n\nexport class SearchSelection extends AppSelection {\n protected selectionContainer: HTMLElement;\n protected selectionCountEl: HTMLElement;\n public selectionForwardBtn: HTMLElement;\n public selectionDeleteBtn: HTMLElement;\n public selectionGotoBtn: HTMLElement;\n\n private isPrivate: boolean;\n\n constructor(private searchSuper: AppSearchSuper, managers: AppManagers, listenerSetter: ListenerSetter) {\n super({\n managers,\n verifyTarget: (e, target) => !!target && this.isSelecting,\n getElementFromTarget: (target) => findUpClassName(target, 'search-super-item'),\n targetLookupClassName: 'search-super-item',\n lookupBetweenParentClassName: 'tabs-tab',\n lookupBetweenElementsQuery: '.search-super-item'\n });\n\n this.isPrivate = !searchSuper.showSender;\n this.attachListeners(searchSuper.container, listenerSetter);\n }\n\n /* public appendCheckbox(element: HTMLElement, checkboxField: CheckboxField) {\n checkboxField.label.classList.add('bubble-select-checkbox');\n\n if(element.classList.contains('document') || element.tagName === 'AUDIO-ELEMENT') {\n element.querySelector('.document, audio-element').append(checkboxField.label);\n } else {\n super.appendCheckbox(bubble, checkboxField);\n }\n } */\n\n public toggleSelection(toggleCheckboxes = true, forceSelection = false) {\n const ret = super.toggleSelection(toggleCheckboxes, forceSelection);\n\n if(ret && toggleCheckboxes) {\n const elements = Array.from(this.searchSuper.tabsContainer.querySelectorAll('.search-super-item')) as HTMLElement[];\n elements.forEach((element) => {\n this.toggleElementCheckbox(element, this.isSelecting);\n });\n }\n\n return ret;\n }\n\n public toggleByElement = (element: HTMLElement) => {\n const mid = +element.dataset.mid;\n const peerId = element.dataset.peerId.toPeerId();\n\n if(!this.toggleMid(peerId, mid)) {\n return;\n }\n\n this.updateElementSelection(element, this.isMidSelected(peerId, mid));\n };\n\n public toggleByMid = (peerId: PeerId, mid: number) => {\n const element = this.searchSuper.mediaTab.contentTab.querySelector(`.search-super-item[data-peer-id=\"${peerId}\"][data-mid=\"${mid}\"]`) as HTMLElement;\n this.toggleByElement(element);\n };\n\n protected onUpdateContainer = (cantForward: boolean, cantDelete: boolean, cantSend: boolean) => {\n const length = this.length();\n replaceContent(this.selectionCountEl, i18n('messages', [length]));\n this.selectionGotoBtn.classList.toggle('hide', length !== 1);\n this.selectionForwardBtn.classList.toggle('hide', cantForward);\n this.selectionDeleteBtn && this.selectionDeleteBtn.classList.toggle('hide', cantDelete);\n };\n\n protected onToggleSelection = (forwards: boolean, animate: boolean) => {\n SetTransition({\n element: this.searchSuper.navScrollableContainer,\n className: 'is-selecting',\n forwards,\n duration: animate ? 200 : 0,\n onTransitionEnd: () => {\n if(!this.isSelecting) {\n this.selectionContainer.remove();\n this.selectionContainer =\n this.selectionForwardBtn =\n this.selectionDeleteBtn =\n null;\n this.selectedText = undefined;\n }\n }\n });\n\n SetTransition({\n element: this.searchSuper.container,\n className: 'is-selecting',\n forwards,\n duration: 200\n });\n\n if(this.isSelecting) {\n if(!this.selectionContainer) {\n const BASE_CLASS = 'search-super-selection';\n this.selectionContainer = document.createElement('div');\n this.selectionContainer.classList.add(BASE_CLASS + '-container');\n\n const btnCancel = ButtonIcon(`close ${BASE_CLASS}-cancel`, {noRipple: true});\n attachClickEvent(btnCancel, () => this.cancelSelection(), {listenerSetter: this.listenerSetter, once: true});\n\n this.selectionCountEl = document.createElement('div');\n this.selectionCountEl.classList.add(BASE_CLASS + '-count');\n\n this.selectionGotoBtn = ButtonIcon(`message ${BASE_CLASS}-goto`);\n\n const attachClickOptions: AttachClickOptions = {listenerSetter: this.listenerSetter};\n attachClickEvent(this.selectionGotoBtn, () => {\n const peerId = [...this.selectedMids.keys()][0];\n const mid = [...this.selectedMids.get(peerId)][0];\n this.cancelSelection();\n\n appImManager.setInnerPeer({peerId, lastMsgId: mid});\n }, attachClickOptions);\n\n this.selectionForwardBtn = ButtonIcon(`forward ${BASE_CLASS}-forward`);\n attachClickEvent(this.selectionForwardBtn, () => {\n const obj: {[fromPeerId: PeerId]: number[]} = {};\n for(const [fromPeerId, mids] of this.selectedMids) {\n obj[fromPeerId] = Array.from(mids).sort((a, b) => a - b);\n }\n\n PopupElement.createPopup(PopupForward, obj, () => {\n this.cancelSelection();\n });\n }, attachClickOptions);\n\n if(this.isPrivate) {\n this.selectionDeleteBtn = ButtonIcon(`delete danger ${BASE_CLASS}-delete`);\n attachClickEvent(this.selectionDeleteBtn, () => {\n const peerId = [...this.selectedMids.keys()][0];\n PopupElement.createPopup(PopupDeleteMessages, peerId, [...this.selectedMids.get(peerId)], 'chat', () => {\n this.cancelSelection();\n });\n }, attachClickOptions);\n }\n\n this.selectionContainer.append(...[\n btnCancel,\n this.selectionCountEl,\n this.selectionGotoBtn,\n this.selectionForwardBtn,\n this.selectionDeleteBtn\n ].filter(Boolean));\n\n const transitionElement = this.selectionContainer;\n transitionElement.style.opacity = '0';\n this.searchSuper.navScrollableContainer.append(transitionElement);\n\n void transitionElement.offsetLeft; // reflow\n transitionElement.style.opacity = '';\n }\n }\n };\n}\n\nexport default class ChatSelection extends AppSelection {\n protected selectionInputWrapper: HTMLElement;\n protected selectionContainer: HTMLElement;\n protected selectionCountEl: HTMLElement;\n public selectionSendNowBtn: HTMLElement;\n public selectionForwardBtn: HTMLElement;\n public selectionDeleteBtn: HTMLElement;\n private selectionLeft: HTMLDivElement;\n private selectionRight: HTMLDivElement;\n\n constructor(\n private chat: Chat,\n private bubbles: ChatBubbles,\n private input: ChatInput,\n managers: AppManagers\n ) {\n super({\n managers,\n getElementFromTarget: (target) => findUpClassName(target, 'grouped-item') || findUpClassName(target, 'bubble'),\n verifyTarget: (e, target) => {\n // LEFT BUTTON\n // проверка внизу нужна для того, чтобы не активировать селект если target потомок .bubble\n const bad = !this.selectedMids.size &&\n !(e.target as HTMLElement).classList.contains('bubble') &&\n !(e.target as HTMLElement).classList.contains('document-selection') &&\n target;\n\n return !bad;\n },\n verifyMouseMoveTarget: (e, element, selecting) => {\n const bad = e.target !== element &&\n !(e.target as HTMLElement).classList.contains('document-selection') &&\n selecting === undefined &&\n !this.selectedMids.size;\n return !bad;\n },\n verifyTouchLongPress: () => !this.chat.input.recording,\n targetLookupClassName: 'bubble',\n lookupBetweenParentClassName: 'bubbles-inner',\n lookupBetweenElementsQuery: '.bubble:not(.is-multiple-documents), .grouped-item',\n isScheduled: chat.type === 'scheduled'\n });\n }\n\n public appendCheckbox(bubble: HTMLElement, checkboxField: CheckboxField) {\n checkboxField.label.classList.add('bubble-select-checkbox');\n\n if(bubble.classList.contains('document-container')) {\n bubble.querySelector('.document, audio-element').append(checkboxField.label);\n } else {\n super.appendCheckbox(bubble, checkboxField);\n }\n }\n\n public toggleSelection(toggleCheckboxes = true, forceSelection = false) {\n const ret = super.toggleSelection(toggleCheckboxes, forceSelection);\n\n if(ret && toggleCheckboxes) {\n for(const mid in this.bubbles.bubbles) {\n if(this.bubbles.skippedMids.has(+mid)) {\n continue;\n }\n\n const bubble = this.bubbles.bubbles[mid];\n this.toggleElementCheckbox(bubble, this.isSelecting);\n }\n }\n\n return ret;\n }\n\n public toggleElementCheckbox(bubble: HTMLElement, show: boolean) {\n if(!this.canSelectBubble(bubble)) return;\n\n const ret = super.toggleElementCheckbox(bubble, show);\n if(ret) {\n const isGrouped = bubble.classList.contains('is-grouped');\n if(isGrouped) {\n this.bubbles.getBubbleGroupedItems(bubble).forEach((item) => this.toggleElementCheckbox(item, show));\n }\n }\n\n return ret;\n }\n\n public toggleByElement = (bubble: HTMLElement): Promise<void> => {\n if(!this.canSelectBubble(bubble)) return;\n\n const mid = +bubble.dataset.mid;\n\n const isGrouped = bubble.classList.contains('is-grouped');\n if(isGrouped) {\n if(!this.isGroupedBubbleSelected(bubble)) {\n const set = this.selectedMids.get(this.chat.peerId);\n if(set) {\n // const mids = await this.chat.getMidsByMid(mid);\n const mids = this.getMidsFromGroupContainer(bubble);\n mids.forEach((mid) => set.delete(mid));\n }\n }\n\n /* const promises = */this.bubbles.getBubbleGroupedItems(bubble).map(this.toggleByElement);\n // await Promise.all(promises);\n return;\n }\n\n if(!this.toggleMid(this.chat.peerId, mid)) {\n return;\n }\n\n const isGroupedItem = bubble.classList.contains('grouped-item');\n if(isGroupedItem) {\n const groupContainer = findUpClassName(bubble, 'bubble');\n const isGroupedSelected = this.isGroupedBubbleSelected(groupContainer);\n const isGroupedMidsSelected = this.isGroupedMidsSelected(groupContainer);\n\n const willChange = isGroupedMidsSelected || isGroupedSelected;\n if(willChange) {\n this.updateElementSelection(groupContainer, isGroupedMidsSelected);\n }\n }\n\n this.updateElementSelection(bubble, this.isMidSelected(this.chat.peerId, mid));\n };\n\n protected toggleByMid = async(peerId: PeerId, mid: number) => {\n const mounted = await this.bubbles.getMountedBubble(mid);\n if(mounted) {\n this.toggleByElement(mounted.bubble);\n }\n };\n\n public isElementShouldBeSelected(element: HTMLElement) {\n const isGrouped = element.classList.contains('is-grouped');\n return super.isElementShouldBeSelected(element) && (!isGrouped || this.isGroupedMidsSelected(element));\n }\n\n protected isGroupedBubbleSelected(bubble: HTMLElement) {\n const groupedCheckboxInput = this.getCheckboxInputFromElement(bubble);\n return groupedCheckboxInput?.checked;\n }\n\n protected getMidsFromGroupContainer(groupContainer: HTMLElement) {\n const elements = this.chat.bubbles.getBubbleGroupedItems(groupContainer);\n if(!elements.length) {\n elements.push(groupContainer);\n }\n\n return elements.map((element) => +element.dataset.mid);\n }\n\n protected isGroupedMidsSelected(groupContainer: HTMLElement) {\n const mids = this.getMidsFromGroupContainer(groupContainer);\n const selectedMids = mids.filter((mid) => this.isMidSelected(this.chat.peerId, mid));\n return mids.length === selectedMids.length;\n }\n\n protected getCheckboxInputFromElement(bubble: HTMLElement) {\n /* let perf = performance.now();\n let checkbox = bubble.firstElementChild.tagName === 'LABEL' && bubble.firstElementChild.firstElementChild as HTMLInputElement;\n console.log('getCheckboxInputFromBubble firstElementChild time:', performance.now() - perf);\n\n perf = performance.now();\n checkbox = bubble.querySelector('label input');\n console.log('getCheckboxInputFromBubble querySelector time:', performance.now() - perf); */\n /* let perf = performance.now();\n let contains = bubble.classList.contains('document-container');\n console.log('getCheckboxInputFromBubble classList time:', performance.now() - perf);\n\n perf = performance.now();\n contains = bubble.className.includes('document-container');\n console.log('getCheckboxInputFromBubble className time:', performance.now() - perf); */\n\n return bubble.classList.contains('document-container') ?\n bubble.querySelector('label input') as HTMLInputElement :\n super.getCheckboxInputFromElement(bubble);\n }\n\n public canSelectBubble(bubble: HTMLElement) {\n return !bubble.classList.contains('service') &&\n !bubble.classList.contains('is-outgoing') &&\n !bubble.classList.contains('is-error') &&\n !bubble.classList.contains('bubble-first') &&\n !bubble.classList.contains('avoid-selection');\n }\n\n protected onToggleSelection = async(forwards: boolean, animate: boolean) => {\n const {needTranslateX, widthFrom, widthTo} = await this.chat.input.center(animate);\n\n SetTransition({\n element: this.listenElement,\n className: 'is-selecting',\n forwards,\n duration: animate ? 200 : 0,\n onTransitionEnd: () => {\n if(!this.isSelecting) {\n this.selectionInputWrapper.remove();\n this.selectionInputWrapper =\n this.selectionContainer =\n this.selectionSendNowBtn =\n this.selectionForwardBtn =\n this.selectionDeleteBtn =\n this.selectionLeft =\n this.selectionRight =\n null;\n this.selectedText = undefined;\n }\n\n /* fastRaf(() => {\n this.bubbles.onScroll();\n }); */\n }\n });\n\n // const chatInput = this.appImManager.chatInput;\n\n const translateButtonsX = widthFrom < widthTo ? undefined : needTranslateX * 2;\n if(this.isSelecting) {\n if(!this.selectionContainer) {\n this.selectionInputWrapper = document.createElement('div');\n this.selectionInputWrapper.classList.add('chat-input-wrapper', 'selection-wrapper');\n\n // const background = document.createElement('div');\n // background.classList.add('chat-input-wrapper-background');\n\n this.selectionContainer = document.createElement('div');\n this.selectionContainer.classList.add('selection-container');\n\n const attachClickOptions: AttachClickOptions = {listenerSetter: this.listenerSetter};\n const btnCancel = ButtonIcon('close', {noRipple: true});\n attachClickEvent(btnCancel, () => this.cancelSelection(), {once: true, listenerSetter: this.listenerSetter});\n\n this.selectionCountEl = document.createElement('div');\n this.selectionCountEl.classList.add('selection-container-count');\n\n if(this.chat.type === 'scheduled') {\n this.selectionSendNowBtn = Button('btn-primary btn-transparent btn-short text-bold selection-container-send', {icon: 'send2'});\n this.selectionSendNowBtn.append(i18n('MessageScheduleSend'));\n attachClickEvent(this.selectionSendNowBtn, () => {\n PopupElement.createPopup(PopupSendNow, this.chat.peerId, [...this.selectedMids.get(this.chat.peerId)], () => {\n this.cancelSelection();\n });\n }, attachClickOptions);\n } else {\n this.selectionForwardBtn = Button('btn-primary btn-transparent text-bold selection-container-forward', {icon: 'forward'});\n this.selectionForwardBtn.append(i18n('Forward'));\n attachClickEvent(this.selectionForwardBtn, () => {\n const obj: {[fromPeerId: PeerId]: number[]} = {};\n for(const [fromPeerId, mids] of this.selectedMids) {\n obj[fromPeerId] = Array.from(mids).sort((a, b) => a - b);\n }\n\n PopupElement.createPopup(PopupForward, obj, () => {\n this.cancelSelection();\n });\n }, attachClickOptions);\n }\n\n this.selectionDeleteBtn = Button('btn-primary btn-transparent danger text-bold selection-container-delete', {icon: 'delete'});\n this.selectionDeleteBtn.append(i18n('Delete'));\n attachClickEvent(this.selectionDeleteBtn, () => {\n PopupElement.createPopup(PopupDeleteMessages, this.chat.peerId, [...this.selectedMids.get(this.chat.peerId)], this.chat.type, () => {\n this.cancelSelection();\n });\n }, attachClickOptions);\n\n const left = this.selectionLeft = document.createElement('div');\n left.classList.add('selection-container-left');\n left.append(btnCancel, this.selectionCountEl);\n\n const right = this.selectionRight = document.createElement('div');\n right.classList.add('selection-container-right');\n right.append(...[\n this.selectionSendNowBtn,\n this.selectionForwardBtn,\n this.selectionDeleteBtn\n ].filter(Boolean))\n\n if(translateButtonsX !== undefined) {\n left.style.transform = `translateX(${-translateButtonsX}px)`;\n right.style.transform = `translateX(${translateButtonsX}px)`;\n }\n\n this.selectionContainer.append(left, right);\n\n // background.style.opacity = '0';\n this.selectionInputWrapper.style.opacity = '0';\n this.selectionInputWrapper.append(/* background, */this.selectionContainer);\n this.input.inputContainer.append(this.selectionInputWrapper);\n\n void this.selectionInputWrapper.offsetLeft; // reflow\n // background.style.opacity = '';\n this.selectionInputWrapper.style.opacity = '';\n }\n\n this.selectionLeft.style.transform = '';\n this.selectionRight.style.transform = '';\n } else if(this.selectionLeft && translateButtonsX !== undefined) {\n this.selectionLeft.style.transform = `translateX(-${translateButtonsX}px)`;\n this.selectionRight.style.transform = `translateX(${translateButtonsX}px)`;\n }\n };\n\n protected onUpdateContainer = (cantForward: boolean, cantDelete: boolean, cantSend: boolean) => {\n replaceContent(this.selectionCountEl, i18n('messages', [this.length()]));\n this.selectionSendNowBtn && this.selectionSendNowBtn.toggleAttribute('disabled', cantSend);\n this.selectionForwardBtn && this.selectionForwardBtn.toggleAttribute('disabled', cantForward);\n this.selectionDeleteBtn && this.selectionDeleteBtn.toggleAttribute('disabled', cantDelete);\n };\n\n protected onCancelSelection = async() => {\n return;\n const promises: Promise<HTMLElement>[] = [];\n for(const [peerId, mids] of this.selectedMids) {\n for(const mid of mids) {\n promises.push(this.bubbles.getMountedBubble(mid).then((m) => m?.bubble));\n }\n }\n\n const bubbles = filterUnique((await Promise.all(promises)).filter(Boolean));\n bubbles.forEach((bubble) => {\n this.toggleByElement(bubble);\n });\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function getSelectedText(): string {\n if(window.getSelection) {\n return window.getSelection().toString();\n // @ts-ignore\n } else if(document.selection) {\n // @ts-ignore\n return document.selection.createRange().text;\n }\n\n return '';\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport contextMenuController from '../../helpers/contextMenuController';\nimport {attachContextMenuListener} from '../../helpers/dom/attachContextMenuListener';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport rootScope from '../../lib/rootScope';\nimport {ButtonMenuItemOptions, ButtonMenuSync} from '../buttonMenu';\n\nexport default class SendMenu {\n public sendMenu: HTMLElement;\n private sendMenuButtons: (ButtonMenuItemOptions & {verify: () => boolean})[];\n private type: 'schedule' | 'reminder';\n\n constructor(options: {\n onSilentClick: () => void,\n onScheduleClick: () => void,\n listenerSetter?: ListenerSetter,\n openSide: string,\n onContextElement: HTMLElement,\n onOpen?: () => boolean\n }) {\n this.sendMenuButtons = [{\n icon: 'mute',\n text: 'Chat.Send.WithoutSound',\n onClick: options.onSilentClick,\n verify: () => this.type === 'schedule'\n }, {\n icon: 'schedule',\n text: 'Chat.Send.ScheduledMessage',\n onClick: options.onScheduleClick,\n verify: () => this.type === 'schedule'\n }, {\n icon: 'schedule',\n text: 'Chat.Send.SetReminder',\n onClick: options.onScheduleClick,\n verify: () => this.type === 'reminder'\n }];\n\n this.sendMenu = ButtonMenuSync({buttons: this.sendMenuButtons, listenerSetter: options.listenerSetter});\n this.sendMenu.classList.add('menu-send', options.openSide);\n\n attachContextMenuListener({\n element: options.onContextElement,\n callback: (e) => {\n if(options.onOpen && !options.onOpen()) {\n return;\n }\n\n this.sendMenuButtons.forEach((button) => {\n button.element.classList.toggle('hide', !button.verify());\n });\n\n cancelEvent(e);\n contextMenuController.openBtnMenu(this.sendMenu);\n },\n listenerSetter: options.listenerSetter\n });\n }\n\n public setPeerId(peerId: PeerId) {\n this.type = peerId === rootScope.myId ? 'reminder' : 'schedule';\n }\n};\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ListenerSetter from '../helpers/listenerSetter';\nimport ripple from './ripple';\nimport {LangPackKey, _i18n} from '../lib/langPack';\nimport getDeepProperty from '../helpers/object/getDeepProperty';\nimport rootScope from '../lib/rootScope';\nimport apiManagerProxy from '../lib/mtproto/mtprotoworker';\nimport simulateEvent from '../helpers/dom/dispatchEvent';\n\nexport type CheckboxFieldOptions = {\n text?: LangPackKey,\n textArgs?: any[],\n name?: string,\n round?: boolean,\n toggle?: boolean,\n stateKey?: string,\n stateValues?: any[],\n stateValueReverse?: boolean,\n disabled?: boolean,\n checked?: boolean,\n restriction?: boolean,\n withRipple?: boolean,\n withHover?: boolean,\n listenerSetter?: ListenerSetter,\n asRadio?: boolean\n};\nexport default class CheckboxField {\n public input: HTMLInputElement;\n public label: HTMLLabelElement;\n public span: HTMLSpanElement;\n public listenerSetter: ListenerSetter;\n\n constructor(options: CheckboxFieldOptions = {}) {\n const label = this.label = document.createElement('label');\n label.classList.add('checkbox-field');\n\n if(options.restriction && !options.toggle) {\n label.classList.add('checkbox-field-restriction');\n }\n\n if(options.round) {\n label.classList.add('checkbox-field-round');\n }\n\n if(options.disabled) {\n this.toggleDisability(true);\n }\n\n this.listenerSetter = options.listenerSetter;\n\n const input = this.input = document.createElement('input');\n input.classList.add('checkbox-field-input');\n input.type = options.asRadio ? 'radio' : 'checkbox';\n if(options.name) {\n input[options.asRadio ? 'name' : 'id'] = 'input-' + options.name;\n }\n\n if(options.checked) {\n input.checked = true;\n }\n\n if(options.stateKey) {\n let loaded = false;\n const onChange = () => {\n if(!loaded) {\n return;\n }\n\n let value: any;\n if(options.stateValues) {\n value = options.stateValues[input.checked ? 1 : 0];\n } else {\n value = input.checked;\n\n if(options.stateValueReverse) {\n value = !value;\n }\n }\n\n rootScope.managers.appStateManager.setByKey(options.stateKey, value);\n };\n\n options.checked === undefined && apiManagerProxy.getState().then((state) => {\n loaded = true;\n const stateValue = getDeepProperty(state, options.stateKey);\n let checked: boolean;\n if(options.stateValues) {\n checked = options.stateValues.indexOf(stateValue) === 1;\n } else {\n checked = stateValue;\n\n if(options.stateValueReverse) {\n checked = !checked;\n }\n }\n\n this.setValueSilently(checked);\n });\n\n if(options.listenerSetter) options.listenerSetter.add(input)('change', onChange);\n else input.addEventListener('change', onChange);\n }\n\n let span: HTMLSpanElement;\n if(options.text) {\n span = this.span = document.createElement('span');\n span.classList.add('checkbox-caption');\n _i18n(span, options.text, options.textArgs);\n } else {\n label.classList.add('checkbox-without-caption');\n }\n\n label.append(input);\n\n if(options.toggle) {\n label.classList.add('checkbox-field-toggle');\n\n if(options.restriction) {\n label.classList.add('checkbox-field-toggle-restriction');\n }\n\n const toggle = document.createElement('div');\n toggle.classList.add('checkbox-toggle');\n label.append(toggle);\n } else {\n const box = document.createElement('div');\n box.classList.add('checkbox-box');\n\n const checkSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n checkSvg.classList.add('checkbox-box-check');\n checkSvg.setAttributeNS(null, 'viewBox', '0 0 24 24');\n const use = document.createElementNS('http://www.w3.org/2000/svg', 'use');\n use.setAttributeNS(null, 'href', '#check');\n use.setAttributeNS(null, 'x', '-1');\n checkSvg.append(use);\n\n const bg = document.createElement('div');\n bg.classList.add('checkbox-box-background');\n\n const border = document.createElement('div');\n border.classList.add('checkbox-box-border');\n\n box.append(border, bg, checkSvg);\n\n label.append(box);\n }\n\n if(span) {\n label.append(span);\n }\n\n if(options.withRipple) {\n label.classList.add('checkbox-ripple', 'hover-effect');\n ripple(label, undefined, undefined, true);\n // label.prepend(input);\n } else if(options.withHover) {\n label.classList.add('hover-effect');\n }\n }\n\n get checked() {\n return this.input.checked;\n }\n\n set checked(checked: boolean) {\n /* if(this.checked === checked) {\n return;\n } */\n\n this.setValueSilently(checked);\n simulateEvent(this.input, 'change');\n }\n\n public setValueSilently(checked: boolean) {\n this.input.checked = checked;\n }\n\n public isDisabled() {\n return this.label.classList.contains('checkbox-disabled');\n }\n\n public toggleDisability(disable: boolean) {\n this.label.classList.toggle('checkbox-disabled', disable);\n this.input.disabled = disable;\n return () => this.toggleDisability(!disable);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport findUpAsChild from '../helpers/dom/findUpAsChild';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport safeAssign from '../helpers/object/safeAssign';\nimport I18n, {LangPackKey} from '../lib/langPack';\nimport CheckboxField from './checkboxField';\nimport Row from './row';\nimport {toast} from './toast';\n\nexport type CheckboxFieldsField = {\n text: LangPackKey,\n description?: LangPackKey,\n restrictionText?: LangPackKey,\n checkboxField?: CheckboxField,\n checked?: boolean,\n nested?: CheckboxFieldsField[],\n nestedTo?: CheckboxFieldsField,\n nestedCounter?: HTMLElement,\n setNestedCounter?: (count: number) => void,\n toggleWith?: {checked?: CheckboxFieldsField[], unchecked?: CheckboxFieldsField[]},\n name?: string,\n row?: Row\n};\n\nexport default class CheckboxFields<K extends CheckboxFieldsField = CheckboxFieldsField> {\n public fields: Array<K>;\n protected listenerSetter: ListenerSetter;\n protected asRestrictions: boolean;\n\n constructor(options: {\n fields: Array<K>,\n listenerSetter: ListenerSetter,\n asRestrictions?: boolean\n }) {\n safeAssign(this, options);\n }\n\n public createField(info: CheckboxFieldsField, isNested?: boolean) {\n if(info.nestedTo && !isNested) {\n return;\n }\n\n const row = info.row = new Row({\n titleLangKey: isNested ? undefined : info.text,\n checkboxField: info.checkboxField = new CheckboxField({\n text: isNested ? info.text : undefined,\n checked: info.nested ? false : info.checked,\n toggle: !isNested,\n listenerSetter: this.listenerSetter,\n restriction: this.asRestrictions && !isNested,\n name: info.name\n }),\n listenerSetter: this.listenerSetter,\n subtitleLangKey: info.description,\n clickable: info.nested ? (e) => {\n if(findUpAsChild(e.target as HTMLElement, row.checkboxField.label)) {\n return;\n }\n\n cancelEvent(e);\n row.container.classList.toggle('accordion-toggler-expanded');\n accordion.classList.toggle('is-expanded');\n } : undefined\n });\n\n if(info.restrictionText) {\n info.checkboxField.input.disabled = true;\n\n attachClickEvent(info.checkboxField.label, (e) => {\n toast(I18n.format(info.restrictionText, true));\n }, {listenerSetter: this.listenerSetter});\n }\n\n const nodes: HTMLElement[] = [row.container];\n let accordion: HTMLElement, nestedCounter: HTMLElement;\n if(info.nested) {\n const container = accordion = document.createElement('div');\n container.classList.add('accordion');\n container.style.setProperty('--max-height', info.nested.length * 48 + 'px');\n const _info = info;\n info.nested.forEach((info) => {\n info.nestedTo ??= _info;\n container.append(...this.createField(info, true).nodes);\n });\n nodes.push(container);\n\n const span = document.createElement('span');\n span.classList.add('tgico-down', 'accordion-icon');\n\n nestedCounter = info.nestedCounter = document.createElement('b');\n this.setNestedCounter(info);\n row.title.append(' ', nestedCounter, ' ', span);\n\n row.container.classList.add('accordion-toggler');\n row.titleRow.classList.add('with-delimiter');\n\n row.checkboxField.setValueSilently(this.getNestedCheckedLength(info) === info.nested.length);\n\n info.toggleWith ??= {checked: info.nested, unchecked: info.nested};\n }\n\n if(info.toggleWith || info.nestedTo) {\n const processToggleWith = info.toggleWith ? (info: CheckboxFieldsField) => {\n const {toggleWith, nested} = info;\n const value = info.checkboxField.checked;\n const arr = value ? toggleWith.checked : toggleWith.unchecked;\n if(!arr) {\n return;\n }\n\n const other = this.fields.filter((i) => arr.includes(i));\n other.forEach((info) => {\n info.checkboxField.setValueSilently(value);\n if(info.nestedTo && !nested) {\n this.setNestedCounter(info.nestedTo);\n }\n\n if(info.toggleWith) {\n processToggleWith(info);\n }\n });\n\n if(info.nested) {\n this.setNestedCounter(info);\n }\n } : undefined;\n\n const processNestedTo = info.nestedTo ? () => {\n const length = this.getNestedCheckedLength(info.nestedTo);\n info.nestedTo.checkboxField.setValueSilently(length === info.nestedTo.nested.length);\n this.setNestedCounter(info.nestedTo, length);\n } : undefined;\n\n this.listenerSetter.add(info.checkboxField.input)('change', () => {\n processToggleWith?.(info);\n processNestedTo?.();\n });\n }\n\n return {row, nodes};\n }\n\n protected getNestedCheckedLength(info: CheckboxFieldsField) {\n return info.nested.reduce((acc, v) => acc + +v.checkboxField.checked, 0);\n }\n\n public setNestedCounter(info: CheckboxFieldsField, count = this.getNestedCheckedLength(info)) {\n info.nestedCounter.textContent = `${count}/${info.nested.length}`;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport InputField, {InputFieldOptions} from './inputField';\n\nexport default class CodeInputField extends InputField {\n constructor(public options: InputFieldOptions & {\n length: number,\n onFill: (code: string) => void\n }) {\n super(Object.assign(options, {\n plainText: true\n }));\n\n const input = this.input as HTMLInputElement;\n input.type = 'tel';\n input.setAttribute('required', '');\n input.autocomplete = 'off';\n\n let lastLength = 0;\n this.input.addEventListener('input', (e) => {\n this.input.classList.remove('error');\n this.setLabel();\n\n const value = this.value.replace(/\\D/g, '').slice(0, options.length);\n this.setValueSilently(value);\n\n const length = this.value.length;\n if(length === options.length) { // submit code\n options.onFill(this.value);\n } else if(length === lastLength) {\n return;\n }\n\n lastLength = length;\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement, {addCancelButton} from './popups';\nimport PopupPeer, {PopupPeerCheckboxOptions, PopupPeerOptions} from './popups/peer';\n\n// type PopupConfirmationOptions = Pick<PopupPeerOptions, 'titleLangKey'>;\nexport type PopupConfirmationOptions = PopupPeerOptions & {\n button: PopupPeerOptions['buttons'][0],\n checkbox?: PopupPeerOptions['checkboxes'][0]\n};\n\nexport default function confirmationPopup<T extends PopupConfirmationOptions>(\n options: T\n): Promise<T['checkboxes'] extends PopupPeerCheckboxOptions[] ? Array<boolean> : (T['checkbox'] extends PopupPeerCheckboxOptions ? boolean : void)> {\n return new Promise<any>((resolve, reject) => {\n const {button, checkbox} = options;\n button.callback = (set) => {\n if(checkbox || !set) {\n resolve(set ? !!set.size : undefined);\n } else {\n resolve(options.checkboxes.map((checkbox) => set.has(checkbox.text)));\n }\n };\n\n const buttons = addCancelButton(options.buttons || [button]);\n const cancelButton = buttons.find((button) => button.isCancel);\n cancelButton.callback = () => {\n reject();\n };\n\n options.buttons = buttons;\n options.checkboxes ??= checkbox && [checkbox];\n\n PopupElement.createPopup(PopupPeer, 'popup-confirmation', options).show();\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_EMOJI_SUPPORTED from '../environment/emojiSupport';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport findUpTag from '../helpers/dom/findUpTag';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport setInnerHTML from '../helpers/dom/setInnerHTML';\nimport fastSmoothScroll from '../helpers/fastSmoothScroll';\nimport {randomLong} from '../helpers/random';\nimport {HelpCountry, HelpCountryCode} from '../layer';\nimport I18n, {i18n} from '../lib/langPack';\nimport wrapEmojiText from '../lib/richTextProcessor/wrapEmojiText';\nimport rootScope from '../lib/rootScope';\nimport {getCountryEmoji} from '../vendor/emoji';\nimport InputField, {InputFieldOptions} from './inputField';\nimport Scrollable from './scrollable';\n\nlet countries: HelpCountry.helpCountry[];\nconst setCountries = () => {\n countries = I18n.countriesList\n .filter((country) => !country.pFlags?.hidden)\n .sort((a, b) => (a.name || a.default_name).localeCompare(b.name || b.default_name));\n};\n\nlet init = () => {\n setCountries();\n rootScope.addEventListener('language_change', () => {\n setCountries();\n });\n};\n\nconst VIRTUAL_COUNTRIES = new Set(['FT']);\n\nexport default class CountryInputField extends InputField {\n private lastCountrySelected: HelpCountry;\n private lastCountryCodeSelected: HelpCountryCode;\n\n private hideTimeout: number;\n private selectWrapper: HTMLElement;\n\n private liMap: Map<string, HTMLLIElement[]>;\n\n constructor(public options: InputFieldOptions & {\n onCountryChange?: (country: HelpCountry.helpCountry, code: HelpCountryCode.helpCountryCode) => void,\n noPhoneCodes?: boolean\n } = {}) {\n super({\n label: 'Country',\n name: randomLong(),\n ...options\n });\n\n if(init) {\n init();\n init = undefined;\n }\n\n this.liMap = new Map();\n\n this.container.classList.add('input-select');\n\n const selectWrapper = this.selectWrapper = document.createElement('div');\n selectWrapper.classList.add('select-wrapper', 'z-depth-3', 'hide');\n\n const arrowDown = document.createElement('span');\n arrowDown.classList.add('arrow', 'arrow-down');\n this.container.append(arrowDown);\n\n const selectList = document.createElement('ul');\n selectWrapper.appendChild(selectList);\n\n const scroll = new Scrollable(selectWrapper);\n\n let initSelect = () => {\n initSelect = null;\n\n countries.forEach((c) => {\n if(options.noPhoneCodes && VIRTUAL_COUNTRIES.has(c.iso2)) {\n return;\n }\n\n const emoji = getCountryEmoji(c.iso2);\n\n const liArr: Array<HTMLLIElement> = [];\n for(let i = 0, length = Math.min(c.country_codes.length, options.noPhoneCodes ? 1 : Infinity); i < length; ++i) {\n const countryCode = c.country_codes[i];\n const li = document.createElement('li');\n\n const wrapped = wrapEmojiText(emoji);\n if(IS_EMOJI_SUPPORTED) {\n const spanEmoji = document.createElement('span');\n setInnerHTML(spanEmoji, wrapped);\n li.append(spanEmoji);\n } else {\n setInnerHTML(li, wrapped);\n }\n\n const el = i18n(c.default_name as any);\n el.dataset.defaultName = c.default_name;\n li.append(el);\n\n if(!options.noPhoneCodes) {\n const span = document.createElement('span');\n span.classList.add('phone-code');\n span.innerText = '+' + countryCode.country_code;\n li.appendChild(span);\n }\n\n liArr.push(li);\n selectList.append(li);\n }\n\n this.liMap.set(c.iso2, liArr);\n });\n\n selectList.addEventListener('mousedown', (e) => {\n if(e.button !== 0) { // other buttons but left shall not pass\n return;\n }\n\n const target = findUpTag(e.target, 'LI')\n this.selectCountryByTarget(target);\n // console.log('clicked', e, countryName, phoneCode);\n });\n\n this.container.appendChild(selectWrapper);\n };\n\n initSelect();\n\n this.input.addEventListener('focus', (e) => {\n if(initSelect) {\n initSelect();\n } else {\n countries.forEach((c) => {\n const arr = this.liMap.get(c.iso2);\n if(!arr) return;\n arr.forEach((li) => li.style.display = '');\n });\n }\n\n clearTimeout(this.hideTimeout);\n this.hideTimeout = undefined;\n\n selectWrapper.classList.remove('hide');\n void selectWrapper.offsetWidth; // reflow\n selectWrapper.classList.add('active');\n\n this.select();\n\n fastSmoothScroll({\n // container: page.pageEl.parentElement.parentElement,\n container: findUpClassName(this.container, 'scrollable-y'),\n element: this.input,\n position: 'start',\n margin: 4\n });\n\n setTimeout(() => {\n if(!mouseDownHandlerAttached) {\n document.addEventListener('mousedown', onMouseDown, {capture: true});\n mouseDownHandlerAttached = true;\n }\n }, 0);\n });\n\n let mouseDownHandlerAttached = false;\n const onMouseDown = (e: MouseEvent) => {\n if(findUpClassName(e.target, 'input-select')) {\n return;\n }\n if(e.target === this.input) {\n return;\n }\n\n this.hidePicker();\n document.removeEventListener('mousedown', onMouseDown, {capture: true});\n mouseDownHandlerAttached = false;\n };\n\n /* false && this.input.addEventListener('blur', function(this: typeof this.input, e) {\n hidePicker();\n\n e.cancelBubble = true;\n }, {capture: true}); */\n\n const onKeyPress = (e: KeyboardEvent) => {\n const key = e.key;\n if(e.ctrlKey || key === 'Control') return false;\n\n // let i = new RegExp('^' + this.value, 'i');\n const _value = this.value.toLowerCase();\n const matches: HelpCountry[] = [];\n countries.forEach((c) => {\n const arr = this.liMap.get(c.iso2);\n if(!arr) {\n return;\n }\n\n const names = [\n c.name,\n c.default_name,\n c.iso2\n ];\n\n names.filter(Boolean).forEach((name) => {\n const abbr = name.split(' ').filter((word) => /\\w/.test(word)).map((word) => word[0]).join('');\n if(abbr.length > 1) {\n names.push(abbr);\n }\n });\n\n const good = !!names.filter(Boolean).find((str) => str.toLowerCase().indexOf(_value) !== -1)/* === 0 */;// i.test(c.name);\n\n arr.forEach((li) => li.style.display = good ? '' : 'none');\n if(good) matches.push(c);\n });\n\n // Код ниже автоматически выберет страну если она осталась одна при поиске\n /* if(matches.length === 1 && matches[0].li.length === 1) {\n if(matches[0].name === lastCountrySelected) return false;\n //console.log('clicking', matches[0]);\n\n var clickEvent = document.createEvent('MouseEvents');\n clickEvent.initEvent('mousedown', true, true);\n matches[0].li[0].dispatchEvent(clickEvent);\n return false;\n } else */if(matches.length === 0) {\n countries.forEach((c) => {\n const arr = this.liMap.get(c.iso2);\n if(!arr) {\n return;\n }\n\n arr.forEach((li) => li.style.display = '');\n });\n } else if(matches.length === 1 && key === 'Enter') {\n cancelEvent(e);\n this.selectCountryByTarget(this.liMap.get(matches[0].iso2)[0]);\n }\n };\n\n this.input.addEventListener('keyup', onKeyPress);\n this.input.addEventListener('keydown', (e) => {\n if(e.key === 'Enter') {\n onKeyPress(e);\n }\n });\n\n arrowDown.addEventListener('mousedown', (e) => {\n if(this.input.matches(':focus')) {\n this.hidePicker();\n this.input.blur();\n } else {\n e.cancelBubble = true;\n e.preventDefault();\n this.input.focus();\n }\n });\n }\n\n public getSelected() {\n return {country: this.lastCountrySelected, code: this.lastCountryCodeSelected};\n }\n\n public hidePicker = () => {\n if(this.hideTimeout !== undefined) return;\n this.selectWrapper.classList.remove('active');\n this.hideTimeout = window.setTimeout(() => {\n this.selectWrapper.classList.add('hide');\n this.hideTimeout = undefined;\n }, 200);\n }\n\n public selectCountryByTarget = (target: HTMLElement) => {\n const defaultName = target.querySelector<HTMLElement>('[data-default-name]').dataset.defaultName;\n const phoneCodeEl = target.querySelector<HTMLElement>('.phone-code');\n const phoneCode = phoneCodeEl?.innerText;\n const countryCode = phoneCode && phoneCode.replace(/\\D/g, '');\n\n replaceContent(this.input, i18n(defaultName as any));\n this.simulateInputEvent();\n this.lastCountrySelected = countries.find((c) => c.default_name === defaultName);\n this.lastCountryCodeSelected = countryCode && this.lastCountrySelected.country_codes.find((_countryCode) => _countryCode.country_code === countryCode);\n\n this.options.onCountryChange?.(this.lastCountrySelected, this.lastCountryCodeSelected);\n this.hidePicker();\n }\n\n public selectCountryByIso2(iso2: string) {\n this.selectCountryByTarget(this.liMap.get(iso2)[0]);\n }\n\n public override(country: HelpCountry, code: HelpCountryCode, countryName?: string) {\n replaceContent(this.input, country ? i18n(country.default_name as any) : countryName);\n this.lastCountrySelected = country;\n this.lastCountryCodeSelected = code;\n this.options.onCountryChange?.(this.lastCountrySelected, this.lastCountryCodeSelected);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {setDirection} from '../helpers/dom/setInnerHTML';\n\nexport default class DivAndCaption<T> {\n public container: HTMLElement;\n public border: HTMLElement;\n public content: HTMLElement;\n public title: HTMLElement;\n public subtitle: HTMLElement;\n\n constructor(protected className: string, public fill?: T) {\n this.container = document.createElement('div');\n this.container.className = className;\n\n this.border = document.createElement('div');\n this.border.classList.add(className + '-border');\n\n this.content = document.createElement('div');\n this.content.classList.add(className + '-content');\n\n this.title = document.createElement('div');\n this.title.classList.add(className + '-title');\n setDirection(this.title);\n\n this.subtitle = document.createElement('div');\n this.subtitle.classList.add(className + '-subtitle');\n setDirection(this.subtitle);\n\n this.content.append(this.title, this.subtitle);\n this.container.append(this.border, this.content);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {IS_MOBILE} from '../environment/userAgent';\nimport {animate} from '../helpers/animation';\nimport liteMode from '../helpers/liteMode';\nimport {Middleware} from '../helpers/middleware';\nimport clamp from '../helpers/number/clamp';\nimport animationIntersector, {AnimationItemGroup, AnimationItemWrapper} from './animationIntersector';\n\ntype DotRendererDot = {\n x: number,\n y: number,\n opacity: number,\n radius: number\n mOpacity: number,\n adding: boolean,\n counter: number,\n path: Path2D\n};\nexport default class DotRenderer implements AnimationItemWrapper {\n public canvas: HTMLCanvasElement;\n private context: CanvasRenderingContext2D;\n private dots: DotRendererDot[];\n\n public paused: boolean;\n public autoplay: boolean;\n public tempId: number;\n\n private dpr: number;\n\n public loop: boolean = true;\n\n constructor(\n private width: number,\n private height: number,\n private multiply?: number\n ) {\n const canvas = this.canvas = document.createElement('canvas');\n const dpr = this.dpr = window.devicePixelRatio;\n canvas.width = width * dpr;\n canvas.height = height * dpr;\n canvas.classList.add('canvas-thumbnail', 'canvas-dots');\n\n this.paused = true;\n this.autoplay = true;\n this.tempId = 0;\n this.context = canvas.getContext('2d');\n }\n\n private prepare() {\n let count = Math.round(this.width * this.height / (35 * (IS_MOBILE ? 2 : 1)));\n count *= this.multiply || 1;\n count = Math.min(!liteMode.isAvailable('chat_spoilers') ? 400 : IS_MOBILE ? 1000 : 2200, count);\n count = Math.round(count);\n const dots: DotRendererDot[] = this.dots = new Array(count);\n\n for(let i = 0; i < count; ++i) {\n dots[i] = this.generateDot();\n }\n }\n\n private generateDot(adding?: boolean): DotRendererDot {\n const x = Math.floor(Math.random() * this.canvas.width);\n const y = Math.floor(Math.random() * this.canvas.height);\n const opacity = adding ? 0 : Math.random();\n const radius = (Math.random() >= .8 ? 1 : 0.5) * this.dpr;\n const path = new Path2D();\n path.arc(x, y, radius, 0, 2 * Math.PI, false);\n return {\n x,\n y,\n opacity,\n radius,\n mOpacity: opacity,\n adding: adding ?? Math.random() >= .5,\n counter: 0,\n path\n };\n }\n\n private draw() {\n const {context, canvas, dots} = this;\n context.clearRect(0, 0, canvas.width, canvas.height);\n context.fillStyle = '#fff';\n\n const add = 0.02;\n for(let i = 0, length = dots.length; i < length; ++i) {\n const dot = dots[i];\n const addOpacity = dot.adding ? add : -add;\n\n dot.mOpacity += addOpacity;\n // if(dot.mOpacity <= 0) dot.mOpacity = dot.opacity;\n\n // const easedOpacity = easing(dot.mOpacity);\n const easedOpacity = clamp(dot.mOpacity, 0, 1);\n context.globalAlpha = easedOpacity;\n context.fill(dot.path);\n\n if(dot.mOpacity <= 0) {\n dot.adding = true;\n\n if(++dot.counter >= 1) {\n dots[i] = this.generateDot(dot.adding);\n }\n } else if(dot.mOpacity >= 1) {\n dot.adding = false;\n }\n }\n }\n\n public remove() {\n this.pause();\n }\n\n public pause() {\n if(this.paused) {\n return;\n }\n\n this.paused = true;\n ++this.tempId;\n }\n\n public renderFirstFrame() {\n if(!this.dots) {\n this.prepare();\n }\n\n this.draw();\n }\n\n public play() {\n if(!this.paused) {\n return;\n }\n\n this.paused = false;\n const tempId = ++this.tempId;\n\n if(!this.dots) {\n this.prepare();\n }\n\n animate(() => {\n if(this.tempId !== tempId || this.paused) {\n return false;\n }\n\n this.draw();\n return true;\n });\n }\n\n public static create({\n width,\n height,\n middleware,\n animationGroup,\n multiply\n }: {\n width: number,\n height: number,\n middleware: Middleware,\n animationGroup: AnimationItemGroup,\n multiply?: number\n }) {\n const dotRenderer = new DotRenderer(width, height, multiply);\n dotRenderer.renderFirstFrame();\n\n animationIntersector.addAnimation({\n animation: dotRenderer,\n group: animationGroup,\n observeElement: dotRenderer.canvas,\n controlled: middleware\n });\n\n return dotRenderer;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {InputFile} from '../layer';\nimport AvatarEdit from './avatarEdit';\nimport AvatarElement from './avatar';\nimport InputField from './inputField';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport ButtonCorner from './buttonCorner';\nimport safeAssign from '../helpers/object/safeAssign';\nimport {NULL_PEER_ID} from '../lib/mtproto/mtproto_config';\n\nexport default class EditPeer {\n public nextBtn: HTMLButtonElement;\n\n public uploadAvatar: () => Promise<InputFile>;\n public avatarEdit: AvatarEdit;\n public avatarElem: AvatarElement;\n\n private inputFields: InputField[];\n private listenerSetter: ListenerSetter;\n\n private peerId: PeerId;\n\n private _disabled = false;\n private avatarSize = 120;\n\n constructor(options: {\n peerId?: EditPeer['peerId'],\n inputFields: EditPeer['inputFields'],\n listenerSetter: ListenerSetter,\n doNotEditAvatar?: boolean,\n withoutAvatar?: boolean,\n nextBtn?: HTMLButtonElement,\n avatarSize?: number,\n popupOptions?: ConstructorParameters<typeof AvatarEdit>[1]\n }) {\n safeAssign(this, options);\n\n this.peerId ||= NULL_PEER_ID;\n\n if(!this.nextBtn) {\n this.nextBtn = ButtonCorner({icon: 'check'});\n } else if(!this.nextBtn.classList.contains('btn-corner')) {\n this.handleChange = () => {\n this.nextBtn.toggleAttribute('disabled', !this.isChanged() || this.disabled);\n };\n }\n\n if(!options.withoutAvatar) {\n this.avatarElem = new AvatarElement();\n this.avatarElem.classList.add('avatar-placeholder', 'avatar-' + this.avatarSize);\n this.avatarElem.updateWithOptions({peerId: this.peerId});\n\n if(!options.doNotEditAvatar) {\n this.avatarEdit = new AvatarEdit((_upload) => {\n this.uploadAvatar = _upload;\n this.handleChange();\n this.avatarElem.remove();\n }, options.popupOptions);\n\n this.avatarEdit.container.append(this.avatarElem);\n }\n }\n\n this.inputFields.forEach((inputField) => {\n this.listenerSetter.add(inputField.input)('input', this.handleChange);\n });\n\n this.handleChange();\n }\n\n public get disabled() {\n return this._disabled;\n }\n\n public set disabled(value) {\n this._disabled = value;\n this.inputFields.forEach((inputField) => inputField.input.toggleAttribute('disabled', value));\n this.handleChange();\n }\n\n public lockWithPromise(promise: Promise<any>, unlockOnSuccess = false) {\n this.disabled = true;\n promise.then(() => {\n if(unlockOnSuccess) {\n this.disabled = false;\n }\n }, () => {\n this.disabled = false;\n });\n }\n\n public isChanged = () => {\n if(this.uploadAvatar) {\n return true;\n }\n\n let changedLength = 0, requiredLength = 0, requiredValidLength = 0;\n this.inputFields.forEach((inputField) => {\n if(inputField.isValid()) {\n if(inputField.isChanged()) {\n ++changedLength;\n }\n\n if(inputField.required) {\n ++requiredValidLength;\n }\n }\n\n if(inputField.required) {\n ++requiredLength;\n }\n });\n\n return requiredLength === requiredValidLength && changedLength > 0;\n };\n\n public handleChange = () => {\n this.nextBtn.classList.toggle('is-visible', this.isChanged());\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport emoticonsDropdown, {EmoticonsDropdown, EmoticonsTab, EMOTICONSSTICKERGROUP} from '..';\nimport GifsMasonry from '../../gifsMasonry';\nimport Scrollable from '../../scrollable';\nimport {putPreloader} from '../../putPreloader';\nimport {AppManagers} from '../../../lib/appManagers/managers';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\n\nexport default class GifsTab implements EmoticonsTab {\n public content: HTMLElement;\n public scrollable: Scrollable;\n public tabId: number;\n\n constructor(private managers: AppManagers) {\n\n }\n\n init() {\n this.content = document.getElementById('content-gifs');\n const gifsContainer = this.content.firstElementChild as HTMLDivElement;\n attachClickEvent(gifsContainer, EmoticonsDropdown.onMediaClick);\n\n const scroll = this.scrollable = new Scrollable(this.content, 'GIFS');\n const masonry = new GifsMasonry(gifsContainer, EMOTICONSSTICKERGROUP, scroll);\n const preloader = putPreloader(this.content, true);\n\n this.managers.appDocsManager.getGifs().then((docs) => {\n docs.forEach((doc) => {\n masonry.add(doc);\n });\n\n preloader.remove();\n });\n\n emoticonsDropdown.addLazyLoadQueueRepeat(masonry.lazyLoadQueue, masonry.processInvisibleDiv);\n\n this.init = null;\n }\n\n onClose() {\n\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../../../lib/appManagers/appDocsManager';\nimport {SliderSuperTab} from '../../slider';\nimport InputSearch from '../../inputSearch';\nimport animationIntersector, {AnimationItemGroup} from '../../animationIntersector';\nimport appSidebarRight from '..';\nimport {AppInlineBotsManager} from '../../../lib/appManagers/appInlineBotsManager';\nimport GifsMasonry from '../../gifsMasonry';\nimport appImManager from '../../../lib/appManagers/appImManager';\nimport mediaSizes from '../../../helpers/mediaSizes';\nimport findUpClassName from '../../../helpers/dom/findUpClassName';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport {NULL_PEER_ID} from '../../../lib/mtproto/mtproto_config';\n\nconst ANIMATIONGROUP: AnimationItemGroup = 'GIFS-SEARCH';\n\nexport default class AppGifsTab extends SliderSuperTab {\n private inputSearch: InputSearch;\n private gifsDiv: HTMLDivElement;\n\n private nextOffset = '';\n private loadedAll = false;\n\n private gifBotPeerId: PeerId;\n private masonry: GifsMasonry;\n\n private searchPromise: ReturnType<AppInlineBotsManager['getInlineResults']>;\n\n public init() {\n this.container.id = 'search-gifs-container';\n\n this.inputSearch = new InputSearch('SearchGifsTitle', (value) => {\n this.reset();\n this.search(value);\n });\n\n this.title.replaceWith(this.inputSearch.container);\n\n this.gifsDiv = document.createElement('div');\n this.gifsDiv.classList.add('gifs-masonry');\n attachClickEvent(this.gifsDiv, this.onGifsClick, {listenerSetter: this.listenerSetter});\n\n this.scrollable.append(this.gifsDiv);\n\n this.masonry = new GifsMasonry(this.gifsDiv, ANIMATIONGROUP, this.scrollable);\n // this.backBtn.parentElement.append(this.inputSearch.container);\n\n appSidebarRight.toggleSidebar(true).then(() => {\n this.search('', true);\n\n this.scrollable.onScrolledBottom = () => {\n this.search(this.inputSearch.value, false);\n };\n });\n }\n\n private onGifsClick = async(e: MouseEvent | TouchEvent) => {\n const target = findUpClassName(e.target, 'gif');\n if(!target) return;\n\n const fileId = target.dataset.docId;\n if(await appImManager.chat.input.sendMessageWithDocument(fileId)) {\n if(mediaSizes.isMobile) {\n appSidebarRight.onCloseBtnClick();\n }\n } else {\n console.warn('got no doc by id:', fileId);\n }\n };\n\n public onClose() {\n this.scrollable.onScrolledBottom = () => {};\n }\n\n public onCloseAfterTimeout() {\n this.reset();\n this.gifsDiv.replaceChildren();\n animationIntersector.checkAnimations(undefined, ANIMATIONGROUP);\n this.inputSearch.remove();\n return super.onCloseAfterTimeout();\n }\n\n private reset() {\n this.searchPromise = null;\n this.nextOffset = '';\n this.loadedAll = false;\n this.masonry.clear();\n }\n\n public async search(query: string, newSearch = true) {\n if(this.searchPromise || this.loadedAll) return;\n\n if(!this.gifBotPeerId) {\n this.gifBotPeerId = (await this.managers.appUsersManager.resolveUsername('gif')).id.toPeerId(false);\n }\n\n try {\n this.searchPromise = this.managers.appInlineBotsManager.getInlineResults(NULL_PEER_ID, this.gifBotPeerId, query, this.nextOffset);\n const {results, next_offset} = await this.searchPromise;\n\n if(this.inputSearch.value !== query) {\n return;\n }\n\n this.searchPromise = null;\n this.nextOffset = next_offset;\n if(newSearch) {\n this.gifsDiv.replaceChildren();\n }\n\n if(results.length) {\n results.forEach((result) => {\n if(result._ === 'botInlineMediaResult' && result.document) {\n this.masonry.add(result.document as MyDocument);\n }\n });\n } else {\n this.loadedAll = true;\n }\n\n this.scrollable.onScroll();\n } catch(err) {\n this.searchPromise = null;\n console.error('gifs loading error:', err);\n throw err;\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTab} from '../../slider';\nimport InputSearch from '../../inputSearch';\nimport LazyLoadQueue from '../../lazyLoadQueue';\nimport appImManager from '../../../lib/appManagers/appImManager';\nimport PopupStickers from '../../popups/stickers';\nimport animationIntersector from '../../animationIntersector';\nimport appSidebarRight from '..';\nimport {StickerSet, StickerSetCovered} from '../../../layer';\nimport {i18n} from '../../../lib/langPack';\nimport findUpClassName from '../../../helpers/dom/findUpClassName';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport forEachReverse from '../../../helpers/array/forEachReverse';\nimport setInnerHTML from '../../../helpers/dom/setInnerHTML';\nimport wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';\nimport attachStickerViewerListeners from '../../stickerViewer';\nimport wrapSticker from '../../wrappers/sticker';\nimport PopupElement from '../../popups';\n\nexport default class AppStickersTab extends SliderSuperTab {\n private inputSearch: InputSearch;\n private setsDiv: HTMLDivElement;\n private lazyLoadQueue: LazyLoadQueue;\n\n public init() {\n this.container.id = 'stickers-container';\n this.container.classList.add('chatlist-container');\n\n this.lazyLoadQueue = new LazyLoadQueue();\n\n this.inputSearch = new InputSearch('StickersTab.SearchPlaceholder', (value) => {\n this.search(value);\n });\n\n this.title.replaceWith(this.inputSearch.container);\n\n this.setsDiv = document.createElement('div');\n this.setsDiv.classList.add('sticker-sets');\n this.scrollable.append(this.setsDiv);\n\n attachStickerViewerListeners({listenTo: this.setsDiv, listenerSetter: this.listenerSetter});\n\n attachClickEvent(this.setsDiv, (e) => {\n const sticker = findUpClassName(e.target, 'sticker-set-sticker');\n if(sticker) {\n const docId = sticker.dataset.docId;\n appImManager.chat.input.sendMessageWithDocument(docId);\n return;\n }\n\n const target = findUpClassName(e.target, 'sticker-set');\n if(!target) return;\n\n const id = target.dataset.stickerSet as string;\n const access_hash = target.dataset.access_hash as string;\n\n const button = findUpClassName(e.target, 'sticker-set-button') as HTMLElement;\n if(button) {\n e.preventDefault();\n e.cancelBubble = true;\n\n button.setAttribute('disabled', 'true');\n\n this.managers.appStickersManager.getStickerSet({id, access_hash}).then((full) => {\n this.managers.appStickersManager.toggleStickerSet(full.set).then((changed) => {\n if(changed) {\n button.textContent = '';\n button.append(i18n(full.set.installed_date ? 'Stickers.SearchAdded' : 'Stickers.SearchAdd'));\n button.classList.toggle('gray', !!full.set.installed_date);\n }\n }).finally(() => {\n // button.style.width = set.installed_date ? '68px' : '52px';\n button.removeAttribute('disabled');\n });\n });\n } else {\n this.managers.appStickersManager.getStickerSet({id, access_hash}).then((full) => {\n PopupElement.createPopup(PopupStickers, full.set).show();\n });\n }\n }, {listenerSetter: this.listenerSetter});\n\n appSidebarRight.toggleSidebar(true).then(() => {\n this.renderFeatured();\n });\n }\n\n public onCloseAfterTimeout() {\n this.setsDiv.replaceChildren();\n animationIntersector.checkAnimations(undefined, 'STICKERS-SEARCH');\n return super.onCloseAfterTimeout();\n }\n\n public renderSet(set: StickerSet.stickerSet) {\n // console.log('renderSet:', set);\n const div = document.createElement('div');\n div.classList.add('sticker-set');\n\n const header = document.createElement('div');\n header.classList.add('sticker-set-header');\n\n const details = document.createElement('div');\n details.classList.add('sticker-set-details');\n details.innerHTML = `<div class=\"sticker-set-name\"></div>`;\n\n setInnerHTML(details.firstElementChild, wrapEmojiText(set.title));\n\n const countDiv = document.createElement('div');\n countDiv.classList.add('sticker-set-count');\n countDiv.append(i18n('Stickers', [set.count]));\n details.append(countDiv);\n\n const button = document.createElement('button');\n button.classList.add('btn-primary', 'btn-color-primary', 'sticker-set-button');\n button.append(i18n(set.installed_date ? 'Stickers.SearchAdded' : 'Stickers.SearchAdd'));\n // button.style.width = set.installed_date ? '68px' : '52px';\n\n if(set.installed_date) {\n button.classList.add('gray');\n }\n\n // ripple(button);\n\n header.append(details, button);\n\n const stickersDiv = document.createElement('div');\n stickersDiv.classList.add('sticker-set-stickers');\n\n const count = Math.min(5, set.count);\n for(let i = 0; i < count; ++i) {\n const stickerDiv = document.createElement('div');\n stickerDiv.classList.add('sticker-set-sticker');\n\n stickersDiv.append(stickerDiv);\n }\n\n this.managers.appStickersManager.getStickerSet(set).then((set) => {\n // console.log('renderSet got set:', set);\n\n for(let i = 0; i < count; ++i) {\n const div = stickersDiv.children[i] as HTMLDivElement;\n const doc = set.documents[i];\n if(doc._ === 'documentEmpty') {\n continue;\n }\n\n wrapSticker({\n doc,\n div,\n lazyLoadQueue: this.lazyLoadQueue,\n group: 'STICKERS-SEARCH',\n /* play: false,\n loop: false, */\n play: true,\n loop: true,\n width: 68,\n height: 68,\n withLock: true\n });\n }\n });\n\n /* const onMouseOver = () => {\n const animations: AnimationItem['animation'][] = [];\n for(let i = 0; i < count; ++i) {\n const stickerDiv = stickersDiv.children[i] as HTMLElement;\n const animationItem = animationIntersector.getAnimation(stickerDiv);\n if(!animationItem) continue;\n\n const animation = animationItem.animation;\n\n animations.push(animation);\n animation.loop = true;\n animation.play();\n }\n\n div.addEventListener('mouseout', () => {\n animations.forEach((animation) => {\n animation.loop = false;\n });\n\n div.addEventListener('mouseover', onMouseOver, {once: true});\n }, {once: true});\n };\n\n div.addEventListener('mouseover', onMouseOver, {once: true}); */\n\n div.dataset.stickerSet = '' + set.id;\n div.dataset.access_hash = '' + set.access_hash;\n div.dataset.title = set.title;\n\n div.append(header, stickersDiv);\n\n this.setsDiv.append(div);\n }\n\n public renderFeatured() {\n return this.managers.appStickersManager.getFeaturedStickers().then((coveredSets) => {\n if(this.inputSearch.value) {\n return;\n }\n\n coveredSets = this.filterRendered('', coveredSets);\n coveredSets.forEach((set) => {\n this.renderSet(set.set);\n });\n });\n }\n\n private filterRendered(query: string, coveredSets: StickerSetCovered[]) {\n coveredSets = coveredSets.slice();\n\n const children = Array.from(this.setsDiv.children) as HTMLElement[];\n forEachReverse(children, el => {\n const id = el.dataset.stickerSet;\n const index = coveredSets.findIndex((covered) => covered.set.id === id);\n\n if(index !== -1) {\n coveredSets.splice(index, 1);\n } else if(!query || !el.dataset.title.toLowerCase().includes(query.toLowerCase())) {\n el.remove();\n }\n });\n\n animationIntersector.checkAnimations(undefined, 'STICKERS-SEARCH');\n\n return coveredSets;\n }\n\n public search(query: string) {\n if(!query) {\n return this.renderFeatured();\n }\n\n return this.managers.appStickersManager.searchStickerSets(query, false).then((coveredSets) => {\n if(this.inputSearch.value !== query) {\n return;\n }\n\n // console.log('search result:', coveredSets);\n\n coveredSets = this.filterRendered(query, coveredSets);\n coveredSets.forEach((set) => {\n this.renderSet(set.set);\n });\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport rootScope from '../../lib/rootScope';\nimport animationIntersector, {AnimationItemGroup} from '../animationIntersector';\nimport {horizontalMenu} from '../horizontalMenu';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport Scrollable, {ScrollableX} from '../scrollable';\nimport appSidebarRight from '../sidebarRight';\nimport StickyIntersector from '../stickyIntersector';\nimport EmojiTab from './tabs/emoji';\nimport GifsTab from './tabs/gifs';\nimport StickersTab, {EmoticonsTabC, StickersTabCategory} from './tabs/stickers';\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport AppGifsTab from '../sidebarRight/tabs/gifs';\nimport AppStickersTab from '../sidebarRight/tabs/stickers';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport findUpTag from '../../helpers/dom/findUpTag';\nimport blurActiveElement from '../../helpers/dom/blurActiveElement';\nimport whichChild from '../../helpers/dom/whichChild';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport DropdownHover from '../../helpers/dropdownHover';\nimport pause from '../../helpers/schedulers/pause';\nimport {IS_APPLE_MOBILE} from '../../environment/userAgent';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport type LazyLoadQueueIntersector from '../lazyLoadQueueIntersector';\nimport {attachClickEvent, simulateClickEvent} from '../../helpers/dom/clickEvent';\nimport overlayCounter from '../../helpers/overlayCounter';\nimport noop from '../../helpers/noop';\nimport {FocusDirection, ScrollOptions} from '../../helpers/fastSmoothScroll';\nimport BezierEasing from '../../vendor/bezier-easing';\nimport RichInputHandler from '../../helpers/dom/richInputHandler';\nimport {getCaretPosF} from '../../helpers/dom/getCaretPosNew';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport {ChatRights} from '../../lib/appManagers/appChatsManager';\nimport {toastNew} from '../toast';\nimport {POSTING_NOT_ALLOWED_MAP} from '../chat/input';\n\nexport const EMOTICONSSTICKERGROUP: AnimationItemGroup = 'emoticons-dropdown';\n\nexport interface EmoticonsTab {\n content: HTMLElement;\n scrollable: Scrollable;\n menuScroll?: ScrollableX;\n tabId: number;\n init: () => void;\n onOpen?: () => void;\n onOpened?: () => void;\n onClose?: () => void;\n onClosed?: () => void;\n}\n\nconst easing = BezierEasing(0.42, 0.0, 0.58, 1.0);\nconst scrollOptions: Partial<ScrollOptions> = {\n forceDuration: 200,\n transitionFunction: easing\n};\n\nexport class EmoticonsDropdown extends DropdownHover {\n public static lazyLoadQueue = new LazyLoadQueue(1);\n\n private emojiTab: EmojiTab;\n private stickersTab: StickersTab;\n private gifsTab: GifsTab;\n\n private container: HTMLElement;\n private tabsEl: HTMLElement;\n private tabId = -1;\n\n private tabs: {[id: number]: EmoticonsTab};\n\n private searchButton: HTMLElement;\n private deleteBtn: HTMLElement;\n\n private selectTab: ReturnType<typeof horizontalMenu>;\n\n private savedRange: Range;\n private managers: AppManagers;\n\n private rights: {[action in ChatRights]?: boolean};\n\n constructor() {\n super({\n element: document.getElementById('emoji-dropdown') as HTMLDivElement,\n ignoreOutClickClassName: 'input-message-input'\n });\n\n this.rights = {\n send_gifs: undefined,\n send_stickers: undefined\n };\n\n this.addEventListener('open', async() => {\n if(IS_TOUCH_SUPPORTED) {\n // appImManager.chat.input.saveScroll();\n if(blurActiveElement()) {\n await pause(100);\n }\n }\n\n if(this.element.parentElement !== appImManager.chat.input.chatInput) {\n appImManager.chat.input.chatInput.append(this.element);\n }\n\n this.savedRange = this.getGoodRange();\n\n EmoticonsDropdown.lazyLoadQueue.lock();\n // EmoticonsDropdown.lazyLoadQueue.unlock();\n animationIntersector.lockIntersectionGroup(EMOTICONSSTICKERGROUP);\n\n const tab = this.tab;\n tab.onOpen?.();\n });\n\n this.addEventListener('opened', () => {\n animationIntersector.unlockIntersectionGroup(EMOTICONSSTICKERGROUP);\n EmoticonsDropdown.lazyLoadQueue.unlockAndRefresh();\n\n // this.container.classList.remove('disable-hover');\n\n const tab = this.tab;\n tab.onOpened?.();\n });\n\n this.addEventListener('close', () => {\n EmoticonsDropdown.lazyLoadQueue.lock();\n // EmoticonsDropdown.lazyLoadQueue.lock();\n\n // нужно залочить группу и выключить стикеры\n animationIntersector.lockIntersectionGroup(EMOTICONSSTICKERGROUP);\n animationIntersector.checkAnimations(true, EMOTICONSSTICKERGROUP);\n\n const tab = this.tab;\n tab.onClose?.();\n });\n\n this.addEventListener('closed', () => {\n // теперь можно убрать visible, чтобы они не включились после фокуса\n animationIntersector.unlockIntersectionGroup(EMOTICONSSTICKERGROUP);\n EmoticonsDropdown.lazyLoadQueue.unlock();\n EmoticonsDropdown.lazyLoadQueue.refresh();\n\n // this.container.classList.remove('disable-hover');\n\n this.savedRange = undefined;\n\n const tab = this.tab;\n tab.onClosed?.();\n });\n }\n\n public get tab() {\n return this.tabs[this.tabId];\n }\n\n public init() {\n this.managers = rootScope.managers;\n this.emojiTab = new EmojiTab({managers: this.managers});\n this.stickersTab = new StickersTab(this.managers);\n this.gifsTab = new GifsTab(this.managers);\n\n this.tabs = {};\n [this.emojiTab, this.stickersTab, this.gifsTab].forEach((tab, idx) => {\n tab.tabId = idx;\n this.tabs[idx] = tab;\n });\n\n this.container = this.element.querySelector('.emoji-container .tabs-container') as HTMLDivElement;\n this.container.prepend(this.emojiTab.container, this.stickersTab.container);\n this.tabsEl = this.element.querySelector('.emoji-tabs') as HTMLUListElement;\n this.selectTab = horizontalMenu(this.tabsEl, this.container, this.onSelectTabClick, () => {\n const {tab} = this;\n tab.init?.();\n animationIntersector.checkAnimations(false, EMOTICONSSTICKERGROUP);\n });\n\n this.searchButton = this.element.querySelector('.emoji-tabs-search');\n this.searchButton.addEventListener('click', () => {\n if(this.tabId === this.stickersTab.tabId) {\n if(!appSidebarRight.isTabExists(AppStickersTab)) {\n appSidebarRight.createTab(AppStickersTab).open();\n }\n } else {\n if(!appSidebarRight.isTabExists(AppGifsTab)) {\n appSidebarRight.createTab(AppGifsTab).open();\n }\n }\n });\n\n this.deleteBtn = this.element.querySelector('.emoji-tabs-delete');\n attachClickEvent(this.deleteBtn, (e) => {\n cancelEvent(e);\n const input = appImManager.chat.input.messageInput;\n // RichInputHandler.getInstance().makeFocused(appImManager.chat.input.messageInput);\n let range = RichInputHandler.getInstance().getSavedRange(input);\n if(!range) {\n range = document.createRange();\n range.setStartAfter(input.lastChild);\n }\n\n const newRange = range.cloneRange();\n // if(range.endOffset === range.startOffset && range.endContainer === range.startContainer) {\n if(range.collapsed) {\n const {node, offset} = getCaretPosF(input, range.endContainer, range.endOffset);\n let newStartNode: Node;\n if(offset) {\n newStartNode = node;\n } else {\n newStartNode = node.previousSibling;\n if(!newStartNode) {\n return;\n }\n\n while(newStartNode.nodeType === newStartNode.TEXT_NODE && !newStartNode.nodeValue && (newStartNode = newStartNode.previousSibling)) {\n\n }\n\n if(newStartNode.nodeType === newStartNode.ELEMENT_NODE && !(newStartNode as HTMLElement).isContentEditable) {\n return;\n }\n }\n\n if(newStartNode.nodeType === newStartNode.ELEMENT_NODE && (newStartNode as any).tagName === 'IMG') {\n newRange.selectNode(newStartNode);\n } else {\n const text = [...newStartNode.textContent];\n let t: string;\n if(offset) {\n let length = 0;\n t = text.find((text) => (length += text.length, length >= offset));\n } else {\n t = text.pop() || '';\n }\n\n const newOffset = offset ? offset - t.length : newStartNode.textContent.length - t.length;\n newRange.setStart(newStartNode, newOffset);\n }\n }\n\n newRange.deleteContents();\n\n appImManager.chat.input.messageInputField.simulateInputEvent();\n // const selection = document.getSelection();\n // if(selection.isCollapsed) {\n // selection.modify('extend', 'backward', 'character');\n // }\n\n // selection.deleteFromDocument();\n // (document.activeElement as HTMLElement).blur();\n\n // document.execCommand('undo', false, null);\n // const input = appImManager.chat.input.messageInput;\n // if((input.lastChild as any)?.tagName) {\n // input.lastElementChild.remove();\n // } else if(input.lastChild) {\n // if(!input.lastChild.textContent.length) {\n // input.lastChild.remove();\n // } else {\n // input.lastChild.textContent = input.lastChild.textContent.slice(0, -1);\n // }\n // }\n\n // const event = new Event('input', {bubbles: true, cancelable: true});\n // appImManager.chat.input.messageInput.dispatchEvent(event);\n // // appSidebarRight.stickersTab.init();\n });\n\n const HIDE_EMOJI_TAB = IS_APPLE_MOBILE && false;\n\n const INIT_TAB_ID = HIDE_EMOJI_TAB ? this.stickersTab.tabId : this.emojiTab.tabId;\n\n if(HIDE_EMOJI_TAB) {\n (this.tabsEl.children[1] as HTMLElement).classList.add('hide');\n }\n\n simulateClickEvent(this.tabsEl.children[INIT_TAB_ID + 1] as HTMLElement);\n if(this.tabs[INIT_TAB_ID].init) {\n this.tabs[INIT_TAB_ID].init(); // onTransitionEnd не вызовется, т.к. это первая открытая вкладка\n }\n\n if(!IS_TOUCH_SUPPORTED) {\n let lastMouseMoveEvent: MouseEvent, mouseMoveEventAttached = false;\n const onMouseMove = (e: MouseEvent) => {\n lastMouseMoveEvent = e;\n };\n overlayCounter.addEventListener('change', (isActive) => {\n if(isActive) {\n if(!mouseMoveEventAttached) {\n document.body.addEventListener('mousemove', onMouseMove);\n mouseMoveEventAttached = true;\n }\n } else if(mouseMoveEventAttached) {\n document.body.removeEventListener('mousemove', onMouseMove);\n if(lastMouseMoveEvent) {\n this.onMouseOut(lastMouseMoveEvent);\n }\n }\n });\n }\n\n appImManager.addEventListener('peer_changing', () => {\n this.toggle(false);\n });\n appImManager.addEventListener('peer_changed', this.checkRights);\n this.checkRights();\n\n return super.init();\n }\n\n public getElement() {\n return this.element;\n }\n\n public scrollTo(tab: EmoticonsTab, element: HTMLElement) {\n tab.scrollable.scrollIntoViewNew({\n element: element as HTMLElement,\n axis: 'y',\n position: 'start',\n ...scrollOptions\n });\n }\n\n private onSelectTabClick = (id: number) => {\n if(this.tabId === id) {\n const {tab} = this;\n this.scrollTo(tab, tab.scrollable.container.firstElementChild as HTMLElement);\n return;\n }\n\n const rights: {[tabId: number]: ChatRights} = {\n [this.stickersTab.tabId]: 'send_stickers',\n [this.gifsTab.tabId]: 'send_gifs'\n };\n\n const action = rights[id];\n if(action && !this.rights[action]) {\n toastNew({langPackKey: POSTING_NOT_ALLOWED_MAP[action]});\n return false;\n }\n\n animationIntersector.checkAnimations(true, EMOTICONSSTICKERGROUP);\n\n this.tabId = id;\n this.searchButton.classList.toggle('hide', this.tabId === this.emojiTab.tabId);\n this.deleteBtn.classList.toggle('hide', this.tabId !== this.emojiTab.tabId);\n };\n\n private checkRights = async() => {\n const {peerId, threadId} = appImManager.chat;\n\n const actions = Object.keys(this.rights) as ChatRights[];\n\n const rights = await Promise.all(actions.map((action) => {\n return this.managers.appMessagesManager.canSendToPeer(peerId, threadId, action);\n }));\n\n actions.forEach((action, idx) => {\n this.rights[action] = rights[idx];\n });\n\n const active = this.tabsEl.querySelector('.active');\n if(active && whichChild(active) !== (this.emojiTab.tabId + 1) && (!this.rights['send_stickers'] || !this.rights['send_gifs'])) {\n this.selectTab(this.emojiTab.tabId, false);\n }\n };\n\n public static menuOnClick = (\n emoticons: EmoticonsTabC<any>,\n menu: HTMLElement,\n scrollable: Scrollable,\n menuScroll?: ScrollableX,\n prevTab?: StickersTabCategory<any>,\n listenerSetter?: ListenerSetter\n ) => {\n let jumpedTo = -1;\n\n const scrollToTab = (tab: typeof prevTab, f?: boolean) => {\n const m = tab.menuScroll || menuScroll;\n if(m) {\n m.scrollIntoViewNew({\n element: tab.elements.menuTab,\n position: 'center',\n axis: 'x',\n getElementPosition: f ? ({elementPosition}) => {\n return elementPosition - 106;\n } : undefined,\n ...scrollOptions\n });\n }\n };\n\n const setActive = (tab: typeof prevTab, scroll = true) => {\n if(tab === prevTab) {\n return false;\n }\n\n let f = false;\n if(prevTab) {\n prevTab.elements.menuTab.classList.remove('active');\n if(prevTab.menuScroll && prevTab.menuScroll !== tab.menuScroll) {\n f = true;\n // scroll to first\n prevTab.menuScroll.container.parentElement.classList.remove('active');\n prevTab.menuScroll.scrollIntoViewNew({\n element: prevTab.menuScroll.container.firstElementChild as HTMLElement,\n forceDirection: scroll ? undefined : FocusDirection.Static,\n position: 'center',\n axis: 'x',\n ...scrollOptions\n });\n }\n }\n\n tab.elements.menuTab.classList.add('active');\n\n if(tab.menuScroll) {\n tab.menuScroll.container.parentElement.classList.add('active');\n scroll && menuScroll.scrollIntoViewNew({\n element: tab.menuScroll.container.parentElement,\n position: 'center',\n axis: 'x',\n ...scrollOptions\n });\n }\n\n if(prevTab) {\n scrollToTab(tab, f);\n }\n\n prevTab = tab;\n\n return true;\n };\n\n const setActiveStatic = (tab: typeof prevTab) => {\n if(prevTab?.local) {\n return;\n }\n\n emoticons.scrollable.scrollTop = tab.elements.container.offsetTop + 1;\n const s = emoticons.menuScroll.container;\n const e = tab.elements.menuTab;\n s.scrollLeft = e.offsetLeft - s.clientWidth / 2 + e.offsetWidth / 2;\n setActive(tab, false);\n };\n\n let scrollingToContent = false;\n const stickyIntersector = new StickyIntersector(scrollable.container, (stuck, target) => {\n if(scrollingToContent) {\n return;\n }\n\n // console.log('sticky scrollTop', stuck, target, scrollable.container.scrollTop, jumpedTo);\n\n if(Math.abs(jumpedTo - scrollable.container.scrollTop) <= 1) {\n return;\n } else {\n jumpedTo = -1;\n }\n\n const tab = emoticons.getCategoryByContainer(target);\n const which = whichChild(target);\n if(!stuck && (which || tab.menuScroll)) {\n return;\n }\n\n setActive(tab);\n });\n\n attachClickEvent(menu, (e) => {\n let target = findUpClassName(e.target as HTMLElement, 'menu-horizontal-div-item');\n if(!target) {\n target = findUpClassName(e.target as HTMLElement, 'menu-horizontal-inner');\n if(!target || target.classList.contains('active')) {\n return;\n }\n\n target = target.firstElementChild.firstElementChild as HTMLElement;\n }\n\n const which = whichChild(target);\n\n const tab = emoticons.getCategoryByMenuTab(target);\n\n /* if(menuScroll) {\n menuScroll.scrollIntoView(target, false, 0);\n } */\n\n if(setActive(tab)) {\n // scrollToTab(tab);\n // return;\n }\n\n let offsetTop = 0, additionalOffset = 0;\n if(which > 0 || tab.menuScroll) {\n const element = tab.elements.container;\n additionalOffset = 1;\n offsetTop = element.offsetTop + additionalOffset; // * due to stickyIntersector\n }\n\n jumpedTo = offsetTop;\n\n scrollingToContent = true;\n scrollable.scrollIntoViewNew({\n element: offsetTop ? tab.elements.container : scrollable.container.firstElementChild,\n position: 'start',\n axis: 'y',\n getElementPosition: offsetTop ? ({elementPosition}) => elementPosition + additionalOffset : undefined,\n ...scrollOptions\n }).finally(() => {\n setActive(tab);\n scrollingToContent = false;\n });\n }, {listenerSetter});\n\n const a = scrollable.onAdditionalScroll ? scrollable.onAdditionalScroll.bind(scrollable) : noop;\n scrollable.onAdditionalScroll = () => {\n emoticons.content.parentElement.classList.toggle('scrolled-top', !scrollable.scrollTop);\n a();\n };\n\n return {stickyIntersector, setActive, setActiveStatic};\n };\n\n public static onMediaClick = async(e: {target: EventTarget | Element}, clearDraft = false, silent?: boolean) => {\n const target = findUpTag(e.target as HTMLElement, 'DIV');\n if(!target) return false;\n\n const docId = target.dataset.docId;\n if(!docId) return false;\n\n return this.sendDocId(docId, clearDraft, silent);\n };\n\n public static async sendDocId(docId: DocId, clearDraft?: boolean, silent?: boolean) {\n if(await appImManager.chat.input.sendMessageWithDocument(docId, undefined, clearDraft, silent)) {\n /* dropdown.classList.remove('active');\n toggleEl.classList.remove('active'); */\n if(emoticonsDropdown.container) {\n emoticonsDropdown.forceClose = true;\n // emoticonsDropdown.container.classList.add('disable-hover');\n emoticonsDropdown.toggle(false);\n }\n\n return true;\n } else {\n console.warn('got no doc by id:', docId);\n return false;\n }\n }\n\n public addLazyLoadQueueRepeat(lazyLoadQueue: LazyLoadQueueIntersector, processInvisibleDiv: (div: HTMLElement) => void) {\n this.addEventListener('close', () => {\n lazyLoadQueue.lock();\n });\n\n this.addEventListener('closed', () => {\n const divs = lazyLoadQueue.intersector.getVisible();\n\n for(const div of divs) {\n processInvisibleDiv(div);\n }\n\n lazyLoadQueue.intersector.clearVisible();\n });\n\n this.addEventListener('opened', () => {\n lazyLoadQueue.unlockAndRefresh();\n });\n }\n\n public getSavedRange() {\n return this.getGoodRange() || this.savedRange;\n }\n\n private getGoodRange() {\n const sel = document.getSelection();\n if(sel.rangeCount && document.activeElement === appImManager.chat.input.messageInput) {\n return sel.getRangeAt(0);\n }\n }\n}\n\nconst emoticonsDropdown = new EmoticonsDropdown();\nMOUNT_CLASS_TO.emoticonsDropdown = emoticonsDropdown;\nexport default emoticonsDropdown;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport emoticonsDropdown, {EmoticonsDropdown, EMOTICONSSTICKERGROUP} from '..';\nimport cancelEvent from '../../../helpers/dom/cancelEvent';\nimport findUpClassName from '../../../helpers/dom/findUpClassName';\nimport {fastRaf} from '../../../helpers/schedulers';\nimport pause from '../../../helpers/schedulers/pause';\nimport appImManager from '../../../lib/appManagers/appImManager';\nimport {LangPackKey} from '../../../lib/langPack';\nimport rootScope from '../../../lib/rootScope';\nimport {emojiFromCodePoints} from '../../../vendor/emoji';\nimport {putPreloader} from '../../putPreloader';\nimport Scrollable, {ScrollableX} from '../../scrollable';\nimport IS_EMOJI_SUPPORTED from '../../../environment/emojiSupport';\nimport IS_TOUCH_SUPPORTED from '../../../environment/touchSupport';\nimport blurActiveElement from '../../../helpers/dom/blurActiveElement';\nimport Emoji from '../../../config/emoji';\nimport fixEmoji from '../../../lib/richTextProcessor/fixEmoji';\nimport wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';\nimport wrapSingleEmoji from '../../../lib/richTextProcessor/wrapSingleEmoji';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport {EmoticonsTabC, StickersTabCategory} from './stickers';\nimport {makeMediaSize} from '../../../helpers/mediaSize';\nimport {AppManagers} from '../../../lib/appManagers/managers';\nimport VisibilityIntersector, {OnVisibilityChangeItem} from '../../visibilityIntersector';\nimport mediaSizes from '../../../helpers/mediaSizes';\nimport wrapStickerSetThumb from '../../wrappers/stickerSetThumb';\nimport attachStickerViewerListeners from '../../stickerViewer';\nimport ListenerSetter from '../../../helpers/listenerSetter';\nimport {Document, StickerSet} from '../../../layer';\nimport {CustomEmojiElement, CustomEmojiRendererElement} from '../../../lib/richTextProcessor/wrapRichText';\nimport findAndSplice from '../../../helpers/array/findAndSplice';\nimport positionElementByIndex from '../../../helpers/dom/positionElementByIndex';\nimport PopupStickers from '../../popups/stickers';\nimport {hideToast, toastNew} from '../../toast';\nimport safeAssign from '../../../helpers/object/safeAssign';\nimport type {AppStickersManager} from '../../../lib/appManagers/appStickersManager';\nimport liteMode from '../../../helpers/liteMode';\nimport PopupElement from '../../popups';\n\nconst loadedURLs: Set<string> = new Set();\nexport function appendEmoji(emoji: string, container?: HTMLElement, prepend = false, unify = false) {\n // const emoji = details.unified;\n // const emoji = (details.unified as string).split('-')\n // .reduce((prev, curr) => prev + String.fromCodePoint(parseInt(curr, 16)), '');\n\n const spanEmoji = document.createElement('span');\n spanEmoji.classList.add('super-emoji');\n\n let kek: DocumentFragment;\n if(unify && !IS_EMOJI_SUPPORTED) {\n kek = wrapSingleEmoji(emoji);\n } else {\n emoji = fixEmoji(emoji);\n kek = wrapEmojiText(emoji);\n }\n\n /* if(!kek.includes('emoji')) {\n console.log(emoji, kek, spanEmoji, emoji.length, new TextEncoder().encode(emoji), emojiUnicode(emoji));\n return;\n } */\n\n // console.log(kek);\n\n spanEmoji.append(kek);\n\n if(spanEmoji.children.length > 1) {\n const first = spanEmoji.firstElementChild;\n spanEmoji.replaceChildren(first);\n }\n\n if(spanEmoji.firstElementChild?.tagName === 'IMG') {\n const image = spanEmoji.firstElementChild as HTMLImageElement;\n\n const url = image.src;\n if(!loadedURLs.has(url)) {\n image.setAttribute('loading', 'lazy');\n const placeholder = document.createElement('span');\n placeholder.classList.add('emoji-placeholder');\n\n if(liteMode.isAvailable('animations')) {\n image.style.opacity = '0';\n placeholder.style.opacity = '1';\n }\n\n image.addEventListener('load', () => {\n fastRaf(() => {\n if(liteMode.isAvailable('animations')) {\n image.style.opacity = '';\n placeholder.style.opacity = '';\n }\n\n spanEmoji.classList.remove('empty');\n\n loadedURLs.add(url);\n });\n }, {once: true});\n\n spanEmoji.append(placeholder);\n }\n }\n\n // spanEmoji = spanEmoji.firstElementChild as HTMLSpanElement;\n // spanEmoji.setAttribute('emoji', emoji);\n if(container) {\n if(prepend) container.prepend(spanEmoji);\n else container.appendChild(spanEmoji);\n }\n\n return spanEmoji;\n}\n\nexport function getEmojiFromElement(element: HTMLElement): {docId?: DocId, emoji: string} {\n const superEmoji = findUpClassName(element, 'super-emoji');\n if(!superEmoji) return;\n\n const firstElementChild = superEmoji.firstElementChild as HTMLElement;\n if(firstElementChild && firstElementChild.classList.contains('custom-emoji')) {\n return {emoji: firstElementChild.dataset.stickerEmoji, docId: firstElementChild.dataset.docId} as const;\n } else {\n if(element.nodeType === element.TEXT_NODE) return {emoji: element.nodeValue};\n if(element.tagName === 'SPAN' && !element.classList.contains('emoji') && element.firstElementChild) {\n element = element.firstElementChild as HTMLElement;\n }\n\n return {emoji: element.getAttribute('alt') || element.innerText} as const;\n }\n}\n\nconst EMOJI_RECENT_ID: (typeof EMOJI_CATEGORIES)[0][0] = 'Emoji.Recent';\nconst EMOJI_RECENT_CATEGORY: (typeof EMOJI_CATEGORIES)[0] = [EMOJI_RECENT_ID, 'recent'];\nconst CUSTOM_EMOJI_RECENT_ID: (typeof EMOJI_CATEGORIES)[0][0] = '';\nconst CUSTOM_EMOJI_RECENT_CATEGORY: (typeof EMOJI_CATEGORIES)[0] = [CUSTOM_EMOJI_RECENT_ID, ''];\nconst EMOJI_CATEGORIES: [LangPackKey | '', string][] = [\n ['Emoji.SmilesAndPeople', 'smile'],\n ['Emoji.AnimalsAndNature', 'animals'],\n ['Emoji.FoodAndDrink', 'eats'],\n ['Emoji.TravelAndPlaces', 'car'],\n ['Emoji.ActivityAndSport', 'sport'],\n ['Emoji.Objects', 'lamp'],\n // ['Emoji.Symbols', 'info'],\n ['Emoji.Flags', 'flag'],\n ['Skin Tones' as any, '']\n];\n\nlet sorted: Map<(typeof EMOJI_CATEGORIES)[0], string[]>;\nfunction prepare() {\n if(sorted) {\n return sorted;\n }\n\n const a: Array<[(typeof EMOJI_CATEGORIES)[0], string[]]> = [\n [CUSTOM_EMOJI_RECENT_CATEGORY, []],\n [EMOJI_RECENT_CATEGORY, []]\n ];\n\n sorted = new Map(a);\n for(const emoji in Emoji) {\n const details = Emoji[emoji];\n const i = '' + details;\n const category = EMOJI_CATEGORIES[+i[0] - 1];\n if(!category) continue; // maybe it's skin tones\n\n let s = sorted.get(category);\n if(!s) {\n s = [];\n sorted.set(category, s);\n }\n\n s[+i.slice(1) || 0] = emoji;\n }\n\n sorted.delete(EMOJI_CATEGORIES.pop());\n EMOJI_CATEGORIES.unshift(CUSTOM_EMOJI_RECENT_CATEGORY, EMOJI_RECENT_CATEGORY);\n const order = EMOJI_CATEGORIES.map(([id]) => id);\n const entries = [...sorted.entries()].sort((a, b) => order.indexOf(a[0][0]) - order.indexOf(b[0][0]));\n sorted = new Map(entries);\n\n return sorted;\n}\n\nconst EMOJI_ELEMENT_SIZE = makeMediaSize(42, 42);\nconst RECENT_MAX_LENGTH = 32;\n\ntype EmojiTabItem = {element: HTMLElement} & ReturnType<typeof getEmojiFromElement>;\ntype EmojiTabCategory = StickersTabCategory<EmojiTabItem, {renderer: CustomEmojiRendererElement}>;\nexport default class EmojiTab extends EmoticonsTabC<EmojiTabCategory> {\n private closeScrollTop: number;\n private menuInnerScroll: ScrollableX;\n private isStandalone?: boolean;\n private noRegularEmoji?: boolean;\n private stickerSetId?: Parameters<AppStickersManager['getLocalStickerSet']>[0];\n private onClick: (emoji: EmojiTabItem) => void;\n private activeEmoji: ReturnType<typeof getEmojiFromElement>;\n private activeElements: EmojiTabItem[];\n\n constructor(options: {\n managers: AppManagers,\n isStandalone?: boolean,\n noRegularEmoji?: boolean,\n stickerSetId?: EmojiTab['stickerSetId'],\n onClick?: EmojiTab['onClick']\n }) {\n super(\n options.managers,\n 'super-emojis',\n () => EMOJI_ELEMENT_SIZE,\n 16,\n 4,\n 0\n );\n\n safeAssign(this, options);\n this.container.classList.add('emoji-padding');\n this.content.id = 'content-emoji';\n this.activeElements = [];\n }\n\n private onCategoryVisibility = ({target, visible}: Pick<OnVisibilityChangeItem, 'target' | 'visible'>) => {\n const category = this.categoriesMap.get(target);\n // console.log(target, visible, category);\n // if(category.local) return;\n\n const renderer = category.elements.renderer;\n const newChildren: HTMLElement[] = [];\n if(renderer) {\n newChildren.push(renderer);\n const customEmojis: Parameters<CustomEmojiRendererElement['add']>[0] = new Map();\n if(visible) {\n newChildren.push(...category.items.map(({docId, element}) => {\n if(!docId) {\n return element;\n }\n\n // return element;\n\n // if(element.firstElementChild) {\n // return element;\n // }\n\n const customEmojiElement = element.firstElementChild as CustomEmojiElement;\n customEmojiElement.clear(false);\n // const customEmojiElement = CustomEmojiElement.create(document.id);\n customEmojis.set(customEmojiElement.docId, new Set([customEmojiElement]));\n // element.append(customEmojiElement);\n return element;\n }));\n\n renderer.add(customEmojis/* , EmoticonsDropdown.lazyLoadQueue */, undefined, undefined, false);\n } else {\n renderer.clearCanvas();\n renderer.middlewareHelper.clean();\n }\n } else if(visible) {\n newChildren.push(...category.items.map(({element}) => element));\n }\n\n // if(visible)\n category.elements.items.replaceChildren(...newChildren);\n\n if(renderer && !visible) {\n const customEmojis: Parameters<CustomEmojiRendererElement['add']>[0] = new Map();\n category.items.forEach(({docId, element}) => {\n if(!docId) {\n return;\n }\n\n const customEmojiElement = element.firstElementChild as CustomEmojiElement;\n customEmojiElement.clear();\n customEmojis.set(customEmojiElement.docId, new Set([customEmojiElement]));\n });\n\n /* const promise = */renderer.add(customEmojis/* , EmoticonsDropdown.lazyLoadQueue */, undefined, true);\n // promise.then(() => {\n // customEmojis.forEach((elements) => {\n // elements.forEach((element) => {\n // if(!element.innerHTML) {\n // console.log('no thumb', element);\n // // debugger;\n // }\n // });\n // });\n\n // const set = customEmojis.get('5766933926429854499');\n // console.log(`wrapped ${customEmojis.size} thumbs`, set && set.values().next().value.innerHTML);\n // });\n }\n\n // if(!visible) {\n // const customEmojis: Parameters<CustomEmojiRendererElement['add']>[0] = {};\n // category.items.forEach((item) => {\n // const {element, document} = item;\n // if(!element.firstElementChild) {\n // return;\n // }\n\n // const customEmojiElement = CustomEmojiElement.create(document.id);\n // customEmojis[customEmojiElement.docId] = new Set([customEmojiElement]);\n // element.firstElementChild.replaceWith(customEmojiElement);\n // });\n\n // renderer.add(customEmojis, EmoticonsDropdown.lazyLoadQueue);\n // }\n };\n\n public destroy() {\n super.destroy();\n this.menuInnerScroll?.destroy();\n }\n\n public init() {\n super.init();\n this.init = undefined;\n\n const intersectionOptions: IntersectionObserverInit = {\n root: this.isStandalone ? this.content : emoticonsDropdown.getElement()\n };\n\n this.categoriesIntersector = new VisibilityIntersector(this.onCategoryVisibility, intersectionOptions);\n\n this.menuOnClickResult = EmoticonsDropdown.menuOnClick(this, this.menu, this.scrollable, this.menuScroll, undefined, this.listenerSetter);\n\n const preloader = putPreloader(this.content, true);\n\n let innerScrollWrapper: HTMLElement;\n\n if(!this.isStandalone) {\n const x = this.menuInnerScroll = new ScrollableX(undefined);\n x.container.classList.add('menu-horizontal-inner-scroll');\n\n innerScrollWrapper = document.createElement('div');\n innerScrollWrapper.classList.add('menu-horizontal-inner');\n innerScrollWrapper.append(x.container);\n }\n\n let preparedMap: ReturnType<typeof prepare>;\n prepare();\n if(!this.noRegularEmoji) {\n preparedMap = prepare();\n } else {\n preparedMap = new Map([\n [[CUSTOM_EMOJI_RECENT_CATEGORY[0], 'recent'], []]\n // [EMOJI_RECENT_CATEGORY, []]\n ]);\n }\n\n preparedMap.forEach((emojis, [titleLangPackKey, icon]) => {\n const category = this.createLocalCategory(titleLangPackKey, titleLangPackKey, icon, !icon);\n category.elements.container.classList.remove('hide');\n category.elements.items.classList.add(icon && !this.isStandalone ? 'is-local' : 'not-local');\n\n emojis.forEach((unified) => {\n /* if(emojiUnicode(emoji) === '1f481-200d-2642') {\n console.log('append emoji', emoji, emojiUnicode(emoji));\n } */\n\n const emoji = emojiFromCodePoints(unified);\n // if(emoji.includes('🕵')) {\n // console.log('toCodePoints', toCodePoints(emoji));\n // emoji = emoji.replace(/(\\u200d[\\u2640\\u2642\\u2695])(?!\\ufe0f)/, '\\ufe0f$1');\n // const zwjIndex = emoji.indexOf('\\u200d');\n // if(zwjIndex !== -1 && !emoji.includes('\\ufe0f')) {\n // /* if(zwjIndex !== (emoji.length - 1)) {\n // emoji = emoji.replace(/(\\u200d)/g, '\\ufe0f$1');\n // } */\n\n // emoji += '\\ufe0f';\n // //emoji += '\\ufe0f';\n // }\n\n // debugger;\n // }\n\n this.addEmojiToCategory({\n category,\n emoji: {emoji},\n batch: true\n });\n\n /* if(category === 'Smileys & Emotion') {\n console.log('appended emoji', emoji, itemsDiv.children[itemsDiv.childElementCount - 1].innerHTML, emojiUnicode(emoji));\n } */\n });\n });\n\n const promise = Promise.all([\n this.isStandalone ? undefined : pause(200),\n !this.noRegularEmoji && this.managers.appEmojiManager.getRecentEmojis('native'),\n !this.isStandalone && this.managers.appEmojiManager.getRecentEmojis('custom'),\n this.stickerSetId && this.managers.appStickersManager.getLocalStickerSet(this.stickerSetId),\n this.managers.appEmojiManager.getCustomEmojis()\n ]).then(([_, recent, recentCustom, mainSet, sets]) => {\n preloader.remove();\n\n if(mainSet) {\n recentCustom = mainSet.documents.map((doc) => doc.id);\n }\n\n const recentCategory = this.categories[EMOJI_RECENT_ID];\n const recentCustomCategory = this.categories[CUSTOM_EMOJI_RECENT_ID];\n\n if(!this.isStandalone) {\n const a = [\n recentCategory && [recentCategory, recent] as const,\n recentCustomCategory && [recentCustomCategory, recentCustom] as const\n ];\n\n a.filter(Boolean).forEach(([category, recent]) => {\n category.limit = RECENT_MAX_LENGTH;\n recent.splice(RECENT_MAX_LENGTH, recent.length - RECENT_MAX_LENGTH);\n });\n }\n\n if(recentCategory && recent) for(const emoji of recent) {\n this.addEmojiToCategory({\n category: recentCategory,\n emoji: {emoji},\n batch: true\n });\n }\n\n if(recentCustomCategory) {\n this.createRendererForCategory(recentCustomCategory);\n if(recentCustom) for(const docId of recentCustom) {\n this.addEmojiToCategory({\n category: recentCustomCategory,\n emoji: {emoji: '', docId},\n batch: true\n });\n }\n recentCustomCategory.elements.container.style.paddingTop = '.5rem';\n }\n\n EMOJI_CATEGORIES.forEach(([id]) => {\n const category = this.categories[id];\n if(!category) {\n return;\n }\n\n this.toggleLocalCategory(category, true);\n\n if(id !== EMOJI_RECENT_ID && id !== CUSTOM_EMOJI_RECENT_ID) {\n category.menuScroll = this.menuInnerScroll;\n this.menuInnerScroll.container.append(category.elements.menuTab);\n }\n });\n\n this.resizeCategories();\n\n recentCategory && innerScrollWrapper && recentCategory.elements.menuTab.after(innerScrollWrapper);\n\n sets.sets.forEach((set) => {\n this.renderStickerSet(set);\n });\n\n this.listenerSetter.add(rootScope)('premium_toggle', () => {\n this.toggleCustomCategory();\n });\n\n this.listenerSetter.add(rootScope)('stickers_top', this.postponedEvent((id) => {\n const category = this.categories[id];\n if(!category) {\n return;\n }\n\n this.positionCategory(category, true);\n\n this.listenerSetter.add(emoticonsDropdown)('openAfterLayout', () => {\n this.menuOnClickResult.setActiveStatic(category);\n }, {once: true});\n }));\n\n const toggleRenderers = (ignore: boolean) => {\n for(const id in this.categories) {\n const category = this.categories[id];\n const renderer = category.elements.renderer;\n if(renderer) {\n renderer.ignoreSettingDimensions = ignore;\n if(!ignore) {\n renderer.setDimensionsFromRect(undefined, true);\n }\n }\n }\n };\n\n !this.isStandalone && this.listenerSetter.add(emoticonsDropdown)('opened', () => {\n toggleRenderers(false);\n });\n\n !this.isStandalone && this.listenerSetter.add(emoticonsDropdown)('close', () => {\n toggleRenderers(true);\n });\n\n this.listenerSetter.add(rootScope)('stickers_installed', (set) => {\n if(!this.categories[set.id] && set.pFlags.emojis) {\n this.renderStickerSet(set, true);\n }\n });\n\n this.listenerSetter.add(rootScope)('stickers_deleted', (set) => {\n const category = this.categories[set.id];\n if(this.deleteCategory(category)) {\n const {renderer} = category.elements;\n if(renderer) {\n renderer.middlewareHelper.clean();\n }\n }\n });\n\n !this.isStandalone && this.listenerSetter.add(rootScope)('emoji_recent', this.postponedEvent((emoji) => {\n const category = this.categories[emoji.docId ? CUSTOM_EMOJI_RECENT_ID : EMOJI_RECENT_ID];\n if(!category) {\n return;\n }\n\n const verify: (item: EmojiTabItem) => boolean = emoji.docId ?\n (item) => item.docId === emoji.docId :\n (item) => item.emoji === emoji.emoji;\n const found = findAndSplice(category.items, verify);\n if(found) {\n category.items.unshift(found);\n if(this.isCategoryVisible(category)) {\n const {renderer} = category.elements;\n positionElementByIndex(found.element, category.elements.items, renderer ? 1 : 0, -1);\n renderer?.forceRender();\n }\n } else {\n this.addEmojiToCategory({\n category,\n emoji,\n batch: false,\n prepend: true\n });\n }\n\n if(this.closeScrollTop === 0) {\n this.menuOnClickResult.setActive(emoji.docId ? this.categories[EMOJI_RECENT_ID] : category);\n }\n }));\n\n !this.isStandalone && this.listenerSetter.add(appImManager)('peer_changed', () => {\n this.toggleCustomCategory();\n });\n\n this.toggleCustomCategory();\n\n this.menuOnClickResult.setActive(recentCategory ?? recentCustomCategory);\n });\n\n attachClickEvent(this.content, this.onContentClick, {listenerSetter: this.listenerSetter});\n attachStickerViewerListeners({listenTo: this.content, listenerSetter: this.listenerSetter});\n\n return promise;\n }\n\n private renderStickerSet(set: StickerSet.stickerSet, prepend?: boolean) {\n const category = this.createCategory(set, wrapEmojiText(set.title));\n this.positionCategory(category, prepend);\n const {container, menuTabPadding} = category.elements;\n category.elements.items.classList.add('not-local');\n category.elements.container.classList.add('is-premium-set');\n category.elements.title.classList.add('tgico');\n\n this.createRendererForCategory(category);\n\n const promise = this.managers.appStickersManager.getStickerSet(set);\n promise.then(({documents}) => {\n documents.forEach((document) => {\n this.addEmojiToCategory({\n category,\n emoji: {docId: document.id, emoji: (document as Document.document).stickerEmojiRaw},\n batch: true\n });\n });\n\n // if(this.isCategoryVisible(category)) {\n // category.elements.items.append(...category.items.map(({element}) => element));\n // }\n\n this.onCategoryVisibility({target: category.elements.container, visible: this.isCategoryVisible(category)});\n\n category.setCategoryItemsHeight();\n container.classList.remove('hide');\n });\n\n wrapStickerSetThumb({\n set,\n container: menuTabPadding,\n group: EMOTICONSSTICKERGROUP,\n lazyLoadQueue: EmoticonsDropdown.lazyLoadQueue,\n width: 32,\n height: 32,\n autoplay: false\n });\n }\n\n private get peerId() {\n return appImManager.chat.peerId;\n }\n\n public getCustomCategory() {\n return this.categories[CUSTOM_EMOJI_RECENT_ID];\n }\n\n private toggleCustomCategory() {\n const category = this.categories[CUSTOM_EMOJI_RECENT_ID];\n const hasPremium = rootScope.premium || this.peerId === rootScope.myId;\n const canSeeCustomCategory = hasPremium || this.isStandalone;\n super.toggleLocalCategory(category, !!category.items.length && canSeeCustomCategory);\n this.content.classList.toggle('has-premium', hasPremium);\n }\n\n protected toggleLocalCategory(category: EmojiTabCategory, visible: boolean) {\n if(category.id === CUSTOM_EMOJI_RECENT_ID) {\n this.toggleCustomCategory();\n return;\n }\n\n super.toggleLocalCategory(category, visible);\n }\n\n private createRendererForCategory(category: EmojiTabCategory) {\n const renderer = CustomEmojiRendererElement.create({\n animationGroup: EMOTICONSSTICKERGROUP,\n customEmojiSize: mediaSizes.active.esgCustomEmoji\n });\n\n category.elements.renderer = renderer;\n category.elements.items.append(renderer);\n }\n\n public addEmojiToCategory(options: {\n category: EmojiTabCategory,\n emoji?: ReturnType<typeof getEmojiFromElement>,\n element?: HTMLElement,\n batch?: boolean,\n prepend?: boolean,\n active?: boolean\n }) {\n const {category, emoji, batch, prepend} = options;\n let element = options.element;\n if(element) {\n const spanEmoji = document.createElement('span');\n spanEmoji.classList.add('super-emoji');\n spanEmoji.append(element);\n element = spanEmoji;\n } else if(emoji.docId) {\n const customEmojiElement = CustomEmojiElement.create(emoji.docId);\n const span = document.createElement('span');\n span.classList.add(/* 'emoji', */'super-emoji');\n span.append(customEmojiElement);\n element = span;\n } else {\n element = appendEmoji(emoji.emoji/* .replace(/[\\ufe0f\\u2640\\u2642\\u2695]/g, '') */, undefined, false/* , false */);\n }\n\n const item: typeof category['items'][0] = {\n ...(emoji || {emoji: undefined}),\n element\n };\n\n if(\n options.active || (\n this.activeEmoji && (\n item.docId ?\n this.activeEmoji.docId === item.docId :\n this.activeEmoji.emoji === item.emoji\n )\n )\n ) {\n this.activeEmoji === emoji;\n this.activeElements.push(item);\n element.classList.add('active');\n }\n\n category.items[prepend ? 'unshift' : 'push'](item);\n if(!batch && !this.spliceExceed(category)) {\n this.onLocalCategoryUpdate(category);\n }\n }\n\n // private addEmojisToCategory(category: EmojiTabCategory, emojis: string[], prepend?: boolean) {\n // emojis.forEach((emoji) => {\n // this.addEmojiToCategory(category, emoji, true, prepend);\n // });\n\n // this.onLocalCategoryUpdate(category);\n // }\n\n private onContentClick = (e: MouseEvent) => {\n cancelEvent(e);\n\n const {target} = e;\n\n const container = findUpClassName(target, 'emoji-category');\n const category = this.categoriesMap.get(container);\n if(findUpClassName(target, 'category-title')) {\n if(category.local) {\n return;\n }\n\n PopupElement.createPopup(PopupStickers, {id: category.set.id, access_hash: category.set.access_hash}, true).show();\n return;\n }\n\n const emoji = getEmojiFromElement(target as HTMLElement);\n if(!emoji) {\n return;\n }\n\n if(\n emoji.docId &&\n !rootScope.premium && (\n this.isStandalone ? category.id !== CUSTOM_EMOJI_RECENT_ID : this.peerId !== rootScope.myId\n )\n ) {\n const a = document.createElement('a');\n a.onclick = () => {\n appImManager.openPremiumBot();\n hideToast();\n };\n toastNew({\n langPackKey: 'CustomEmoji.PremiumAlert',\n langPackArguments: [a]\n });\n return;\n }\n\n if(this.onClick) {\n this.onClick({\n ...emoji,\n element: findUpClassName(target, 'super-emoji').firstElementChild as HTMLElement\n });\n } else {\n appImManager.chat.input.onEmojiSelected(emoji, false);\n }\n\n if(IS_TOUCH_SUPPORTED) {\n blurActiveElement();\n }\n };\n\n public setActive(emoji: ReturnType<typeof getEmojiFromElement>) {\n if(\n emoji === this.activeEmoji ||\n emoji?.docId ? emoji.docId === this.activeEmoji?.docId : emoji?.emoji === this.activeEmoji?.emoji\n ) {\n return;\n }\n\n this.activeEmoji = emoji;\n\n this.activeElements.forEach((item) => {\n item.element.classList.remove('active');\n });\n\n this.activeElements.length = 0;\n\n this.categoriesMap.forEach((category) => {\n category.items.forEach((item) => {\n if(emoji.docId ? item.docId === emoji.docId : item.emoji === emoji.emoji) {\n item.element.classList.add('active');\n this.activeElements.push(item);\n }\n });\n });\n }\n\n public onClose() {\n this.closeScrollTop = this.scrollable.scrollTop;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport getEmojiEntityFromEmoji from './getEmojiEntityFromEmoji';\nimport wrapRichText from './wrapRichText';\n\nexport default function wrapSingleEmoji(emoji: string) {\n return wrapRichText(emoji, {\n entities: [getEmojiEntityFromEmoji(emoji)]\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport indexOfAndSplice from '../helpers/array/indexOfAndSplice';\nimport LazyLoadQueueIntersector, {LazyLoadElement} from './lazyLoadQueueIntersector';\nimport VisibilityIntersector, {OnVisibilityChange} from './visibilityIntersector';\n\nexport default class LazyLoadQueueRepeat extends LazyLoadQueueIntersector {\n private elementsMap: Map<HTMLElement, LazyLoadElement> = new Map();\n\n constructor(\n parallelLimit?: number,\n protected onVisibilityChange?: OnVisibilityChange,\n options?: IntersectionObserverInit\n ) {\n super(parallelLimit);\n\n this.intersector = new VisibilityIntersector((item) => {\n const {target, visible} = item;\n\n const queueItem = this.elementsMap.get(target);\n queueItem.visible = visible;\n\n if(visible) {\n queueItem.wasSeen = true;\n if(!this.queue.includes(queueItem)) {\n this.queue.push(queueItem);\n }\n } else {\n indexOfAndSplice(this.queue, queueItem);\n }\n\n this.onVisibilityChange?.(item);\n this.setProcessQueueTimeout();\n }, options);\n }\n\n public clear() {\n super.clear();\n this.elementsMap.clear();\n }\n\n /* public async processItem(item: LazyLoadElement) {\n //await super.processItem(item);\n await LazyLoadQueueBase.prototype.processItem.call(this, item);\n\n if(this.lazyLoadMedia.length) {\n this.processQueue();\n }\n } */\n\n public observe(el: LazyLoadElement) {\n this.elementsMap.set(el.div, el);\n super.observe(el);\n }\n\n public unobserve(el: LazyLoadElement) {\n this.elementsMap.delete(el.div);\n super.unobserve(el);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport emoticonsDropdown, {EmoticonsDropdown, EMOTICONSSTICKERGROUP, EmoticonsTab} from '..';\nimport findUpClassName from '../../../helpers/dom/findUpClassName';\nimport mediaSizes from '../../../helpers/mediaSizes';\nimport {Document, MessagesAllStickers, StickerSet} from '../../../layer';\nimport {MyDocument} from '../../../lib/appManagers/appDocsManager';\nimport {AppManagers} from '../../../lib/appManagers/managers';\nimport {i18n, LangPackKey} from '../../../lib/langPack';\nimport wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';\nimport rootScope from '../../../lib/rootScope';\nimport animationIntersector, {AnimationItemGroup} from '../../animationIntersector';\nimport LazyLoadQueue from '../../lazyLoadQueue';\nimport LazyLoadQueueRepeat from '../../lazyLoadQueueRepeat';\nimport {putPreloader} from '../../putPreloader';\nimport PopupStickers from '../../popups/stickers';\nimport Scrollable, {ScrollableX} from '../../scrollable';\nimport findAndSplice from '../../../helpers/array/findAndSplice';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport positionElementByIndex from '../../../helpers/dom/positionElementByIndex';\nimport noop from '../../../helpers/noop';\nimport ButtonIcon from '../../buttonIcon';\nimport confirmationPopup from '../../confirmationPopup';\nimport VisibilityIntersector, {OnVisibilityChangeItem} from '../../visibilityIntersector';\nimport createStickersContextMenu from '../../../helpers/dom/createStickersContextMenu';\nimport findUpAsChild from '../../../helpers/dom/findUpAsChild';\nimport forEachReverse from '../../../helpers/array/forEachReverse';\nimport attachStickerViewerListeners from '../../stickerViewer';\nimport ListenerSetter from '../../../helpers/listenerSetter';\nimport wrapSticker from '../../wrappers/sticker';\nimport wrapStickerSetThumb from '../../wrappers/stickerSetThumb';\nimport {MediaSize} from '../../../helpers/mediaSize';\nimport {AnyFunction} from '../../../types';\nimport {IgnoreMouseOutType} from '../../../helpers/dropdownHover';\nimport customProperties from '../../../helpers/dom/customProperties';\nimport windowSize from '../../../helpers/windowSize';\nimport PopupElement from '../../popups';\n\nexport class SuperStickerRenderer {\n public lazyLoadQueue: LazyLoadQueueRepeat;\n private animated: Set<HTMLElement> = new Set();\n\n constructor(\n private regularLazyLoadQueue: LazyLoadQueue,\n private group: AnimationItemGroup,\n private managers: AppManagers,\n private options?: IntersectionObserverInit\n ) {\n this.lazyLoadQueue = new LazyLoadQueueRepeat(undefined, ({target, visible}) => {\n if(!visible) {\n this.processInvisible(target);\n }\n }, options);\n }\n\n public clear() {\n this.lazyLoadQueue.clear();\n }\n\n public renderSticker(doc: MyDocument, element?: HTMLElement, loadPromises?: Promise<any>[]) {\n if(!element) {\n element = document.createElement('div');\n element.classList.add('grid-item', 'super-sticker');\n element.dataset.docId = '' + doc.id;\n\n if(doc.animated) {\n this.observeAnimated(element);\n }\n }\n\n // * This will wrap only a thumb\n /* !doc.animated && */wrapSticker({\n doc,\n div: element,\n lazyLoadQueue: this.regularLazyLoadQueue,\n group: this.group,\n onlyThumb: doc.animated,\n loadPromises\n });\n\n return element;\n }\n\n public observeAnimated(element: HTMLElement) {\n this.animated.add(element);\n this.lazyLoadQueue.observe({\n div: element,\n load: this.processVisible\n });\n }\n\n public unobserveAnimated(element: HTMLElement) {\n this.animated.delete(element);\n this.lazyLoadQueue.delete({div: element});\n }\n\n private checkAnimationContainer = (element: HTMLElement, visible: boolean) => {\n // console.error('checkAnimationContainer', div, visible);\n const players = animationIntersector.getAnimations(element);\n players.forEach((player) => {\n if(!visible) {\n animationIntersector.removeAnimation(player);\n } else {\n animationIntersector.checkAnimation(player, false);\n }\n });\n };\n\n private processVisible = async(element: HTMLElement) => {\n const docId = element.dataset.docId;\n const doc = await this.managers.appDocsManager.getDoc(docId);\n\n const size = mediaSizes.active.esgSticker.width;\n\n // console.log('processVisibleDiv:', element);\n\n const promise = wrapSticker({\n doc,\n div: element,\n width: size,\n height: size,\n lazyLoadQueue: null,\n group: this.group,\n onlyThumb: false,\n play: true,\n loop: true,\n withLock: true\n }).then(({render}) => render);\n\n promise.then(() => {\n // clearTimeout(timeout);\n this.checkAnimationContainer(element, this.lazyLoadQueue.intersector.isVisible(element));\n });\n\n /* let timeout = window.setTimeout(() => {\n console.error('processVisibleDiv timeout', div, doc);\n }, 1e3); */\n\n return promise;\n };\n\n public processInvisible = async(element: HTMLElement) => {\n const docId = element.dataset.docId;\n const doc = await this.managers.appDocsManager.getDoc(docId);\n\n // console.log('STICKER INvisible:', /* div, */docId);\n\n this.checkAnimationContainer(element, false);\n\n element.textContent = '';\n this.renderSticker(doc, element as HTMLDivElement);\n };\n}\n\nexport type StickersTabCategoryItem = {element: HTMLElement};\n\nexport class StickersTabCategory<Item extends StickersTabCategoryItem, AdditionalElements extends Record<string, HTMLElement> = {}> {\n public elements: {\n container: HTMLElement,\n title: HTMLElement,\n items: HTMLElement,\n menuTab: HTMLElement,\n menuTabPadding: HTMLElement\n } & AdditionalElements;\n public items: Item[];\n public mounted: boolean;\n public id: string;\n public limit: number;\n\n public getContainerSize: () => {width: number, height: number};\n private getElementMediaSize: () => MediaSize;\n\n private gapX: number;\n private gapY: number;\n\n public set?: StickerSet;\n public local?: boolean;\n public menuScroll?: ScrollableX;\n\n constructor(options: {\n id: string,\n title: HTMLElement | DocumentFragment,\n overflowElement: HTMLElement,\n getContainerSize: StickersTabCategory<Item>['getContainerSize'],\n getElementMediaSize: StickersTabCategory<Item>['getElementMediaSize'],\n gapX: number,\n gapY: number,\n noMenuTab?: boolean\n }) {\n const container = document.createElement('div');\n container.classList.add('emoji-category');\n\n const items = document.createElement('div');\n items.classList.add('category-items');\n\n let title: HTMLElement;\n if(options.title) {\n title = document.createElement('div');\n title.classList.add('category-title');\n title.append(options.title);\n }\n\n let menuTab: HTMLElement, menuTabPadding: HTMLElement;\n if(!options.noMenuTab) {\n menuTab = ButtonIcon(undefined, {noRipple: true});\n menuTab.classList.add('menu-horizontal-div-item');\n\n menuTabPadding = document.createElement('div');\n menuTabPadding.classList.add('menu-horizontal-div-item-padding');\n\n menuTab.append(menuTabPadding);\n }\n\n if(title) container.append(title);\n container.append(items);\n\n this.elements = {\n container,\n title,\n items,\n menuTab,\n menuTabPadding\n } as any;\n this.id = options.id;\n this.items = [];\n\n this.getContainerSize = options.getContainerSize;\n this.getElementMediaSize = options.getElementMediaSize;\n this.gapX = options.gapX ?? 0;\n this.gapY = options.gapY ?? 0;\n }\n\n public setCategoryItemsHeight() {\n const {width: containerWidth} = this.getContainerSize();\n const elementSize = this.getElementMediaSize().width;\n\n let itemsPerRow = containerWidth / elementSize;\n if(this.gapX) itemsPerRow -= Math.floor(itemsPerRow - 1) * this.gapX / elementSize;\n itemsPerRow = Math.floor(itemsPerRow);\n\n const rows = Math.ceil(this.items.length / itemsPerRow);\n let height = rows * elementSize;\n if(this.gapY) height += (rows - 1) * this.gapY;\n\n this.elements.items.style.minHeight = height + 'px';\n }\n}\n\nexport class EmoticonsTabC<Category extends StickersTabCategory<any, any>> implements EmoticonsTab {\n public content: HTMLElement;\n public menuScroll: ScrollableX;\n public container: HTMLElement;\n public menuWrapper: HTMLElement;\n public menu: HTMLElement;\n\n protected categories: {[id: string]: Category};\n protected categoriesMap: Map<HTMLElement, Category>;\n protected categoriesByMenuTabMap: Map<HTMLElement, Category>;\n protected categoriesIntersector: VisibilityIntersector;\n protected localCategories: Category[];\n\n protected listenerSetter: ListenerSetter;\n\n public scrollable: Scrollable;\n protected mounted = false;\n protected menuOnClickResult: ReturnType<typeof EmoticonsDropdown['menuOnClick']>;\n\n public tabId: number;\n\n protected postponedEvents: {cb: AnyFunction, args: any[]}[];\n\n public getContainerSize: Category['getContainerSize'];\n\n constructor(\n protected managers: AppManagers,\n protected categoryItemsClassName: string,\n protected getElementMediaSize: () => MediaSize,\n protected padding: number,\n protected gapX: number,\n protected gapY: number\n ) {\n this.categories = {};\n this.categoriesMap = new Map();\n this.categoriesByMenuTabMap = new Map();\n this.localCategories = [];\n this.postponedEvents = [];\n\n this.listenerSetter = new ListenerSetter();\n\n this.container = document.createElement('div');\n this.container.classList.add('tabs-tab', 'emoticons-container');\n\n this.menuWrapper = document.createElement('div');\n this.menuWrapper.classList.add('menu-wrapper', 'emoticons-menu-wrapper');\n\n this.menu = document.createElement('nav');\n this.menu.className = 'menu-horizontal-div no-stripe justify-start emoticons-menu';\n\n this.menuWrapper.append(this.menu);\n this.menuScroll = new ScrollableX(this.menuWrapper);\n\n this.content = document.createElement('div');\n this.content.classList.add('emoticons-content');\n\n this.container.append(this.menuWrapper, this.content);\n\n this.scrollable = new Scrollable(this.content, 'STICKERS');\n }\n\n public getCategoryByContainer(container: HTMLElement) {\n return this.categoriesMap.get(container);\n }\n\n public getCategoryByMenuTab(menuTab: HTMLElement) {\n return this.categoriesByMenuTabMap.get(menuTab);\n }\n\n protected createCategory(stickerSet: StickerSet, title: HTMLElement | DocumentFragment, isLocal?: boolean, noMenuTab?: boolean) {\n const category: Category = new StickersTabCategory({\n id: '' + stickerSet.id,\n title,\n overflowElement: this.content,\n getContainerSize: () => {\n let width: number, height: number;\n if(this.getContainerSize) {\n const size = this.getContainerSize();\n width = size.width;\n height = size.height;\n } else {\n const esgWidth = customProperties.getPropertyAsSize('esg-width');\n width = esgWidth === undefined ? windowSize.width : esgWidth;\n }\n\n return {width: width - this.padding, height};\n },\n getElementMediaSize: this.getElementMediaSize,\n gapX: this.gapX,\n gapY: this.gapY,\n noMenuTab\n }) as any;\n\n if(this.categoryItemsClassName) {\n category.elements.items.classList.add(this.categoryItemsClassName);\n }\n\n const container = category.elements.container;\n container.classList.add('hide');\n\n category.set = stickerSet;\n this.categories[stickerSet.id] = category;\n this.categoriesMap.set(container, category);\n !noMenuTab && this.categoriesByMenuTabMap.set(category.elements.menuTab, category);\n\n this.categoriesIntersector.observe(container);\n !noMenuTab && this.menuOnClickResult.stickyIntersector.observeStickyHeaderChanges(container);\n\n if(!isLocal) {\n !noMenuTab && category.elements.menuTab.classList.add('not-local');\n }\n\n return category;\n }\n\n protected positionCategory(category: Category, prepend?: boolean) {\n const {menuTab, container} = category.elements;\n const posItems = prepend ? this.localCategories.filter((category) => category.mounted).length : 0xFFFF;\n let foundMenuScroll = false;\n const posMenu = prepend ? this.localCategories.filter((category) => {\n if(category.menuScroll && !foundMenuScroll) {\n foundMenuScroll = true;\n return true;\n }\n\n return category.mounted && !category.menuScroll && category.elements.menuTab;\n }).length : 0xFFFF;\n positionElementByIndex(container, this.scrollable.container, posItems);\n positionElementByIndex(menuTab, this.menu, posMenu);\n }\n\n protected isCategoryVisible(category: Category) {\n return this.categoriesIntersector.getVisible().includes(category.elements.container);\n }\n\n protected toggleLocalCategory(category: Category, visible: boolean) {\n if(!visible) {\n category.elements.menuTab?.remove();\n category.elements.container.remove();\n } else {\n const idx = this.localCategories.indexOf(category);\n const sliced = this.localCategories.slice(0, idx);\n let notMountedItems = 0, notMountedMenus = 0;\n sliced.forEach((category) => {\n if(!category.mounted) {\n ++notMountedItems;\n ++notMountedMenus;\n } else if(!category.elements.menuTab || category.menuScroll) {\n ++notMountedMenus;\n }\n });\n const itemsIdx = idx - notMountedItems, menuIdx = idx - notMountedMenus;\n category.elements.menuTab && positionElementByIndex(category.elements.menuTab, this.menu, menuIdx);\n positionElementByIndex(category.elements.container, this.scrollable.container, itemsIdx);\n }\n\n category.mounted = visible;\n // category.elements.container.classList.toggle('hide', !visible);\n }\n\n protected createLocalCategory(id: string, title: LangPackKey | '', icon?: string, noMenuTab?: boolean) {\n const category = this.createCategory({id} as any, title && i18n(title), true, noMenuTab);\n category.local = true;\n this.localCategories.push(category);\n if(category.elements.title) {\n category.elements.title.classList.add('disable-hover');\n }\n\n if(!noMenuTab) {\n if(icon) {\n category.elements.menuTab.classList.add('tgico', 'tgico-' + icon);\n }\n\n category.elements.menuTabPadding.remove();\n }\n\n this.toggleLocalCategory(category, false);\n return category;\n }\n\n protected onLocalCategoryUpdate(category: Category) {\n category.setCategoryItemsHeight();\n this.toggleLocalCategory(category, !!category.items.length);\n }\n\n protected resizeCategories = () => {\n for(const [container, category] of this.categoriesMap) {\n category.setCategoryItemsHeight();\n }\n };\n\n protected deleteCategory(category: Category) {\n if(category) {\n category.elements.container.remove();\n category.elements.menuTab.remove();\n this.categoriesIntersector.unobserve(category.elements.container);\n delete this.categories[category.id];\n this.categoriesMap.delete(category.elements.container);\n this.categoriesByMenuTabMap.delete(category.elements.menuTab);\n\n return true;\n }\n\n return false;\n }\n\n protected spliceExceed(category: Category) {\n if(category.limit === undefined) {\n return false;\n }\n\n const {items, limit} = category;\n items.splice(limit, items.length - limit).forEach(({element}) => {\n element.remove();\n });\n\n this.onLocalCategoryUpdate(category);\n\n return true;\n }\n\n public init() {\n this.listenerSetter.add(emoticonsDropdown)('closed', () => {\n this.postponedEvents.forEach(({cb, args}) => {\n cb(...args);\n });\n\n this.postponedEvents.length = 0;\n });\n }\n\n public destroy() {\n this.getContainerSize = undefined;\n this.postponedEvents.length = 0;\n this.categoriesIntersector?.disconnect();\n this.listenerSetter.removeAll();\n this.scrollable.destroy();\n this.menuScroll?.destroy();\n this.menuOnClickResult?.stickyIntersector?.disconnect();\n }\n\n protected postponedEvent = <K>(cb: (...args: K[]) => void) => {\n return (...args: K[]) => {\n if(emoticonsDropdown.isActive()) {\n this.postponedEvents.push({cb, args});\n } else {\n cb(...args);\n }\n };\n };\n}\n\ntype StickersTabItem = {element: HTMLElement, document: Document.document};\nexport default class StickersTab extends EmoticonsTabC<StickersTabCategory<StickersTabItem>> {\n private superStickerRenderer: SuperStickerRenderer;\n\n constructor(managers: AppManagers) {\n super(\n managers,\n 'super-stickers',\n () => mediaSizes.active.esgSticker,\n 3 * 2,\n 4,\n 4\n );\n\n this.container.classList.add('stickers-padding');\n this.content.id = 'content-stickers';\n }\n\n private setFavedLimit(limit: number) {\n const category = this.categories['faved'];\n category.limit = limit;\n }\n\n private categoryAppendStickers(\n category: StickersTabCategory<StickersTabItem>,\n promise: Promise<MyDocument[]>\n ) {\n const {container} = category.elements;\n\n promise.then((documents) => {\n const isVisible = this.isCategoryVisible(category);\n\n documents.forEach((document) => {\n const element = this.superStickerRenderer.renderSticker(document);\n category.items.push({document, element});\n\n if(isVisible) {\n category.elements.items.append(element);\n }\n });\n\n category.setCategoryItemsHeight();\n container.classList.remove('hide');\n });\n }\n\n private async renderStickerSet(set: StickerSet.stickerSet, prepend = false) {\n const category = this.createCategory(set, wrapEmojiText(set.title));\n const {menuTabPadding} = category.elements;\n\n const promise = this.managers.appStickersManager.getStickerSet(set);\n this.categoryAppendStickers(\n category,\n promise.then((stickerSet) => stickerSet.documents as MyDocument[])\n );\n\n this.positionCategory(category, prepend);\n\n wrapStickerSetThumb({\n set,\n container: menuTabPadding,\n group: EMOTICONSSTICKERGROUP,\n lazyLoadQueue: EmoticonsDropdown.lazyLoadQueue,\n width: 32,\n height: 32,\n autoplay: false\n });\n }\n\n private onCategoryVisibility = ({target, visible, entry}: OnVisibilityChangeItem) => {\n const category = this.categoriesMap.get(target);\n category.elements.items.replaceChildren(...(!visible ? [] : category.items.map(({element}) => element)));\n };\n\n public init() {\n super.init();\n\n this.scrollable.onAdditionalScroll = () => {\n this.setTyping();\n };\n\n /* stickersDiv.addEventListener('mouseover', (e) => {\n let target = e.target as HTMLElement;\n\n if(target.tagName === 'CANVAS') { // turn on sticker\n let animation = lottieLoader.getAnimation(target.parentElement, EMOTICONSSTICKERGROUP);\n\n if(animation) {\n // @ts-ignore\n if(animation.currentFrame === animation.totalFrames - 1) {\n animation.goToAndPlay(0, true);\n } else {\n animation.play();\n }\n }\n }\n }); */\n\n const intersectionOptions: IntersectionObserverInit = {root: emoticonsDropdown.getElement()};\n this.categoriesIntersector = new VisibilityIntersector(this.onCategoryVisibility, intersectionOptions);\n\n const clearCategoryItems = (category: StickersTabCategory<StickersTabItem>) => {\n category.elements.items.replaceChildren();\n category.items.forEach(({element}) => this.superStickerRenderer.unobserveAnimated(element));\n category.items.length = 0;\n };\n\n this.scrollable.container.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if(findUpClassName(target, 'category-title')) {\n const container = findUpClassName(target, 'emoji-category');\n const category = this.categoriesMap.get(container);\n if(category.local) {\n return;\n }\n\n PopupElement.createPopup(PopupStickers, {id: category.set.id, access_hash: category.set.access_hash}).show();\n return;\n }\n\n EmoticonsDropdown.onMediaClick(e);\n });\n\n this.menuOnClickResult = EmoticonsDropdown.menuOnClick(this, this.menu, this.scrollable, this.menuScroll);\n\n const preloader = putPreloader(this.content, true);\n\n const onCategoryStickers = (category: StickersTabCategory<StickersTabItem>, stickers: MyDocument[]) => {\n // if(category.id === 'faved' && category.limit && category.limit < stickers.length) {\n // category.limit = stickers.length;\n // }\n\n if(category.limit) {\n stickers = stickers.slice(0, category.limit);\n }\n\n const ids = new Set(stickers.map((doc) => doc.id));\n forEachReverse(category.items, (item) => {\n if(!ids.has(item.document.id)) {\n this.deleteSticker(category, item.document, true);\n }\n });\n\n this.toggleLocalCategory(category, !!stickers.length);\n forEachReverse(stickers, (doc, idx) => {\n this.unshiftSticker(category, doc, true, idx);\n });\n this.spliceExceed(category);\n category.elements.container.classList.remove('hide');\n };\n\n const favedCategory = this.createLocalCategory('faved', 'FavoriteStickers', 'savedmessages');\n // favedCategory.elements.menuTab.classList.add('active');\n\n const recentCategory = this.createLocalCategory('recent', 'Stickers.Recent', 'recent');\n recentCategory.limit = 20;\n\n const clearButton = ButtonIcon('close', {noRipple: true});\n recentCategory.elements.title.append(clearButton);\n attachClickEvent(clearButton, () => {\n confirmationPopup({\n titleLangKey: 'ClearRecentStickersAlertTitle',\n descriptionLangKey: 'ClearRecentStickersAlertMessage',\n button: {\n langKey: 'Clear'\n }\n }).then(() => {\n this.managers.appStickersManager.clearRecentStickers();\n }, noop);\n });\n\n const premiumCategory = this.createLocalCategory('premium', 'PremiumStickersShort');\n const s = document.createElement('span');\n s.classList.add('tgico-star', 'color-premium');\n premiumCategory.elements.menuTab.append(s);\n\n const promises = [\n Promise.all([\n this.managers.apiManager.getLimit('favedStickers'),\n this.managers.appStickersManager.getFavedStickersStickers()\n ]).then(([limit, stickers]) => {\n this.setFavedLimit(limit);\n onCategoryStickers(favedCategory, stickers);\n }),\n\n this.managers.appStickersManager.getRecentStickersStickers().then((stickers) => {\n onCategoryStickers(recentCategory, stickers);\n }),\n\n this.managers.appStickersManager.getAllStickers().then((res) => {\n for(const set of (res as MessagesAllStickers.messagesAllStickers).sets) {\n this.renderStickerSet(set);\n }\n }),\n\n this.managers.appStickersManager.getPremiumStickers().then((stickers) => {\n const length = stickers.length;\n this.toggleLocalCategory(premiumCategory, rootScope.premium && !!length);\n this.categoryAppendStickers(premiumCategory, Promise.resolve(stickers));\n\n rootScope.addEventListener('premium_toggle', (isPremium) => {\n this.toggleLocalCategory(this.categories['premium'], isPremium && !!length);\n });\n })\n ];\n\n Promise.race(promises).finally(() => {\n preloader.remove();\n });\n\n Promise.all(promises).finally(() => {\n this.mounted = true;\n this.setTyping();\n\n const favedCategory = this.categories['faved'];\n const recentCategory = this.categories['recent'];\n this.menuOnClickResult.setActive(favedCategory.items.length ? favedCategory : recentCategory);\n\n rootScope.addEventListener('stickers_installed', (set) => {\n if(!this.categories[set.id]) {\n this.renderStickerSet(set, true);\n }\n });\n });\n\n this.superStickerRenderer = new SuperStickerRenderer(EmoticonsDropdown.lazyLoadQueue, EMOTICONSSTICKERGROUP, this.managers, intersectionOptions);\n\n const rendererLazyLoadQueue = this.superStickerRenderer.lazyLoadQueue;\n emoticonsDropdown.addLazyLoadQueueRepeat(rendererLazyLoadQueue, this.superStickerRenderer.processInvisible);\n\n // emoticonsDropdown.addEventListener('close', () => {\n // this.categoriesIntersector.lock();\n // });\n\n // emoticonsDropdown.addEventListener('closed', () => {\n // for(const [container] of this.categoriesMap) {\n // onCategoryVisibility(container, false);\n // }\n // });\n\n // emoticonsDropdown.addEventListener('opened', () => {\n // this.categoriesIntersector.unlockAndRefresh();\n // });\n\n // setInterval(() => {\n // // @ts-ignore\n // const players = Object.values(lottieLoader.players).filter((p) => p.width >= 80);\n\n // console.log(\n // 'STICKERS RENDERED IN PANEL:',\n // players.length,\n // players.filter((p) => !p.paused).length,\n // rendererLazyLoadQueue.intersector.getVisible().length\n // );\n // }, .25e3);\n\n rootScope.addEventListener('sticker_updated', ({type, document, faved}) => {\n // if(type === 'faved') {\n // return;\n // }\n\n const category = this.categories[type === 'faved' ? 'faved' : 'recent'];\n if(category) {\n if(faved) {\n this.unshiftSticker(category, document);\n } else {\n this.deleteSticker(category, document);\n }\n }\n });\n\n rootScope.addEventListener('stickers_deleted', ({id}) => {\n const category = this.categories[id];\n if(this.deleteCategory(category)) {\n clearCategoryItems(category);\n }\n });\n\n rootScope.addEventListener('stickers_top', this.postponedEvent((id) => {\n const category = this.categories[id];\n if(category) {\n this.positionCategory(category, true);\n emoticonsDropdown.addEventListener('openAfterLayout', () => {\n this.menuOnClickResult.setActiveStatic(category);\n }, {once: true});\n }\n }));\n\n rootScope.addEventListener('stickers_order', ({type, order}) => {\n if(type !== 'stickers') {\n return;\n }\n\n order.forEach((id) => {\n const category = this.categories[id];\n if(category) {\n this.positionCategory(category, false);\n }\n });\n });\n\n rootScope.addEventListener('stickers_updated', ({type, stickers}) => {\n const category = this.categories[type === 'faved' ? 'faved' : 'recent'];\n if(category) {\n onCategoryStickers(category, stickers);\n }\n });\n\n rootScope.addEventListener('app_config', () => {\n this.managers.apiManager.getLimit('favedStickers').then((limit) => {\n this.setFavedLimit(limit);\n });\n });\n\n mediaSizes.addEventListener('resize', this.resizeCategories);\n\n attachStickerViewerListeners({listenTo: this.content, listenerSetter: new ListenerSetter()});\n\n const type: IgnoreMouseOutType = 'menu';\n createStickersContextMenu({\n listenTo: this.content,\n verifyRecent: (target) => !!findUpAsChild(target, this.categories['recent'].elements.items),\n onOpen: () => {\n emoticonsDropdown.setIgnoreMouseOut(type, true);\n },\n onClose: () => {\n emoticonsDropdown.setIgnoreMouseOut(type, false);\n }\n });\n\n this.init = null;\n }\n\n public deleteSticker(category: StickersTabCategory<StickersTabItem>, doc: MyDocument, batch?: boolean) {\n const item = findAndSplice(category.items, (item) => item.document.id === doc.id);\n if(item) {\n item.element.remove();\n\n if(!batch) {\n this.onLocalCategoryUpdate(category);\n }\n }\n }\n\n public unshiftSticker(category: StickersTabCategory<StickersTabItem>, doc: MyDocument, batch?: boolean, idx?: number) {\n if(idx !== undefined) {\n const i = category.items[idx];\n if(i && i.document.id === doc.id) {\n return;\n }\n }\n\n let item = findAndSplice(category.items, (item) => item.document.id === doc.id);\n if(!item) {\n item = {\n element: this.superStickerRenderer.renderSticker(doc),\n document: doc\n };\n }\n\n category.items.unshift(item);\n category.elements.items.prepend(item.element);\n\n if(!batch) {\n this.spliceExceed(category);\n }\n }\n\n public unshiftRecentSticker(doc: MyDocument) {\n this.managers.appStickersManager.saveRecentSticker(doc.id);\n }\n\n public deleteRecentSticker(doc: MyDocument) {\n this.managers.appStickersManager.saveRecentSticker(doc.id, true);\n }\n\n public setTyping = (cancel = false) => {\n if(!cancel && (!emoticonsDropdown.isActive() || emoticonsDropdown.tab !== this)) {\n return;\n }\n\n rootScope.dispatchEvent('choosing_sticker', !cancel);\n };\n\n public onClosed() {\n this.setTyping(true);\n }\n\n public onOpened() {\n this.setTyping();\n this.resizeCategories();\n }\n}\n","export const generateDelimiter = () => {\n const delimiter = document.createElement('div');\n delimiter.classList.add('gradient-delimiter');\n return delimiter;\n};\n","import {_i18n} from '../lib/langPack';\n\nexport default function generateFakeIcon(isScam?: boolean) {\n const span = document.createElement('span');\n span.classList.add('badge-fake');\n _i18n(span, isScam ? 'ScamMessage' : 'FakeMessage');\n return span;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport findAndSpliceAll from '../helpers/array/findAndSpliceAll';\nimport LazyLoadQueueIntersector, {LazyLoadElement} from './lazyLoadQueueIntersector';\nimport VisibilityIntersector, {OnVisibilityChange} from './visibilityIntersector';\n\nexport default class LazyLoadQueueRepeat2 extends LazyLoadQueueIntersector {\n constructor(parallelLimit?: number, protected onVisibilityChange?: OnVisibilityChange) {\n super(parallelLimit);\n\n this.intersector = new VisibilityIntersector((item) => {\n const {target, visible} = item;\n const spliced = findAndSpliceAll(this.queue, (i) => i.div === target);\n if(visible && spliced.length) {\n spliced.forEach((item) => {\n this.queue.unshift(item);\n });\n }\n\n this.onVisibilityChange && this.onVisibilityChange(item);\n this.setProcessQueueTimeout();\n });\n }\n\n public observe(el: LazyLoadElement) {\n super.observe(el);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../lib/appManagers/appDocsManager';\nimport animationIntersector, {AnimationItemGroup} from './animationIntersector';\nimport Scrollable from './scrollable';\nimport deferredPromise, {CancellablePromise} from '../helpers/cancellablePromise';\nimport calcImageInBox from '../helpers/calcImageInBox';\nimport {doubleRaf} from '../helpers/schedulers';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport rootScope from '../lib/rootScope';\nimport LazyLoadQueueRepeat2 from './lazyLoadQueueRepeat2';\nimport wrapVideo from './wrappers/video';\nimport noop from '../helpers/noop';\n\nconst width = 400;\nconst maxSingleWidth = width - 100;\nconst height = 100;\n\nexport default class GifsMasonry {\n public lazyLoadQueue: LazyLoadQueueRepeat2;\n private scrollPromise: CancellablePromise<void> = Promise.resolve();\n private timeout: number = 0;\n private managers: AppManagers;\n\n constructor(\n private element: HTMLElement,\n private group: AnimationItemGroup,\n private scrollable: Scrollable,\n attach = true\n ) {\n this.managers = rootScope.managers;\n\n this.lazyLoadQueue = new LazyLoadQueueRepeat2(undefined, ({target, visible}) => {\n if(visible) {\n this.processVisibleDiv(target);\n } else {\n this.processInvisibleDiv(target);\n }\n });\n\n /* setInterval(() => {\n // @ts-ignore\n const players = animationIntersector.byGroups[group];\n\n if(players) {\n console.log(`GIFS RENDERED IN ${group}:`, players.length, players.filter((p) => !p.animation.paused).length, this.lazyLoadQueue.intersector.getVisible().length);\n }\n }, .25e3); */\n\n if(attach) {\n this.attach();\n }\n }\n\n private onScroll = () => {\n if(this.timeout) {\n clearTimeout(this.timeout);\n } else {\n this.scrollPromise = deferredPromise<void>();\n // animationIntersector.checkAnimations(true, group);\n }\n\n this.timeout = window.setTimeout(() => {\n this.timeout = 0;\n this.scrollPromise.resolve();\n // animationIntersector.checkAnimations(false, group);\n }, 150);\n };\n\n public attach() {\n this.scrollable.container.addEventListener('scroll', this.onScroll);\n }\n\n public detach() {\n this.clear();\n this.scrollable.container.removeEventListener('scroll', this.onScroll);\n }\n\n public clear() {\n this.lazyLoadQueue.clear();\n }\n\n private processVisibleDiv(div: HTMLElement) {\n const video = div.querySelector('video');\n if(video) {\n return;\n }\n\n const load = () => {\n const docId = div.dataset.docId;\n const promise = Promise.all([this.managers.appDocsManager.getDoc(docId), this.scrollPromise]).then(async([doc]) => {\n const res = await wrapVideo({\n doc,\n container: div as HTMLDivElement,\n lazyLoadQueue: null,\n // lazyLoadQueue: EmoticonsDropdown.lazyLoadQueue,\n group: this.group,\n noInfo: true,\n noPreview: true\n });\n\n const promise = res.loadPromise;\n promise.finally(() => {\n const video = div.querySelector('video');\n const thumb = div.querySelector('img, canvas');\n\n // div.style.opacity = '';\n thumb && thumb.classList.add('hide');\n\n if(video && !video.parentElement) {\n setTimeout(() => {\n video.src = '';\n video.load();\n const animations = animationIntersector.getAnimations(video);\n animations.forEach((item) => {\n animationIntersector.removeAnimation(item);\n });\n }, 0);\n }\n\n // clearTimeout(timeout);\n if(!this.lazyLoadQueue.intersector.isVisible(div)) {\n this.processInvisibleDiv(div);\n }\n });\n\n return promise;\n });\n\n /* let timeout = window.setTimeout(() => {\n console.error('processVisibleDiv timeout', div, doc);\n }, 1e3); */\n\n return promise;\n };\n\n // return load();\n\n this.lazyLoadQueue.push({div, load});\n }\n\n public processInvisibleDiv = (div: HTMLElement) => {\n return this.scrollPromise.then(async() => {\n // return;\n\n if(this.lazyLoadQueue.intersector.isVisible(div)) {\n return;\n }\n\n const video = div.querySelector('video');\n const thumb = div.querySelector('img, canvas');\n\n if(thumb) {\n thumb.classList.remove('hide');\n\n await doubleRaf();\n }\n\n if(this.lazyLoadQueue.intersector.isVisible(div)) {\n return;\n }\n\n if(video) {\n video.remove();\n video.src = '';\n video.load();\n const animations = animationIntersector.getAnimations(video);\n animations.forEach((item) => {\n animationIntersector.removeAnimation(item);\n });\n }\n });\n };\n\n public add(doc: MyDocument, appendTo = this.element) {\n // let gifWidth = doc.w;\n // let gifHeight = doc.h;\n // if(gifHeight < height) {\n // gifWidth = height / gifHeight * gifWidth;\n // gifHeight = height;\n // }\n\n // const willUseWidth = Math.min(maxSingleWidth, width, gifWidth);\n // const size = calcImageInBox(gifWidth, gifHeight, willUseWidth, height);\n\n const div = document.createElement('div');\n div.classList.add('gif', 'grid-item'/* , 'fade-in-transition' */);\n // div.style.width = size.width + 'px';\n // div.style.opacity = '0';\n // div.style.height = h + 'px';\n div.dataset.docId = '' + doc.id;\n\n appendTo.append(div);\n\n this.lazyLoadQueue.observe({div, load: noop as any});\n\n // let preloader = new ProgressivePreloader(div);\n\n wrapVideo({\n doc,\n container: div as HTMLDivElement,\n lazyLoadQueue: null,\n noInfo: true,\n onlyPreview: true\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport TransitionSlider from './transition';\nimport {ScrollableX} from './scrollable';\nimport rootScope from '../lib/rootScope';\nimport {fastRaf} from '../helpers/schedulers';\nimport {FocusDirection} from '../helpers/fastSmoothScroll';\nimport findUpAsChild from '../helpers/dom/findUpAsChild';\nimport whichChild from '../helpers/dom/whichChild';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport liteMode from '../helpers/liteMode';\n\nexport function horizontalMenu(\n tabs: HTMLElement,\n content: HTMLElement,\n onClick?: (id: number, tabContent: HTMLDivElement, animate: boolean) => void | boolean | Promise<void | boolean>,\n onTransitionEnd?: () => void,\n transitionTime = 200,\n scrollableX?: ScrollableX,\n listenerSetter?: ListenerSetter\n) {\n const selectTab = TransitionSlider({\n content,\n type: tabs || content.dataset.animation === 'tabs' ? 'tabs' : 'navigation',\n transitionTime,\n onTransitionEnd,\n listenerSetter\n });\n\n if(!tabs) {\n return selectTab;\n }\n\n const proxy = new Proxy(selectTab, {\n apply: (target, that, args) => {\n const id = +args[0];\n const animate = args[1] !== undefined ? args[1] : true;\n\n const el = (tabs.querySelector(`[data-tab=\"${id}\"]`) || tabs.children[id]) as HTMLElement;\n selectTarget(el, id, animate);\n }\n });\n\n const selectTarget = async(target: HTMLElement, id: number, animate = true) => {\n const tabContent = content.children[id] as HTMLDivElement;\n\n if(onClick) {\n const result1 = onClick(id, tabContent, animate);\n const canChange = result1 instanceof Promise ? await result1 : result1;\n if(canChange !== undefined && !canChange) {\n return;\n }\n }\n\n if(scrollableX) {\n scrollableX.scrollIntoViewNew({\n element: target.parentElement.children[id] as HTMLElement,\n position: 'center',\n forceDirection: animate ? undefined : FocusDirection.Static,\n forceDuration: transitionTime,\n axis: 'x'\n });\n }\n\n if(!liteMode.isAvailable('animations')) {\n animate = false;\n }\n\n const prevId = selectTab.prevId();\n if(target.classList.contains('active') || id === prevId) {\n return false;\n }\n\n const mutateCallback = animate ? fastRaf : (cb: () => void) => cb();\n\n const prev = tabs.querySelector(tagName.toLowerCase() + '.active') as HTMLElement;\n if(prev) {\n mutateCallback(() => {\n prev.classList.remove('active');\n });\n }\n\n // a great stripe from Jolly Cobra\n if(useStripe && prevId !== -1 && animate) {\n mutateCallback(() => {\n const indicator = target.querySelector('i')!;\n const currentIndicator = target.parentElement.children[prevId].querySelector('i')!;\n\n currentIndicator.classList.remove('animate');\n indicator.classList.remove('animate');\n\n // We move and resize our indicator so it repeats the position and size of the previous one.\n const shiftLeft = currentIndicator.parentElement.parentElement.offsetLeft - indicator.parentElement.parentElement.offsetLeft;\n const scaleFactor = currentIndicator.clientWidth / indicator.clientWidth;\n indicator.style.transform = `translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`;\n\n // console.log(`translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`);\n\n fastRaf(() => {\n // Now we remove the transform to let it animate to its own position and size.\n indicator.classList.add('animate');\n indicator.style.transform = 'none';\n });\n });\n }\n\n mutateCallback(() => {\n target.classList.add('active');\n });\n\n selectTab(id, animate);\n };\n\n const useStripe = !tabs.classList.contains('no-stripe');\n\n // const tagName = tabs.classList.contains('menu-horizontal-div') ? 'BUTTON' : 'LI';\n const tagName = tabs.firstElementChild.tagName;\n attachClickEvent(tabs, (e) => {\n let target = e.target as HTMLElement;\n\n target = findUpAsChild(target, tabs);\n\n // console.log('tabs click:', target);\n\n if(!target) return false;\n\n let id: number;\n if(target.dataset.tab) {\n id = +target.dataset.tab;\n if(id === -1) {\n return false;\n }\n } else {\n id = whichChild(target);\n }\n\n selectTarget(target, id);\n }, {listenerSetter});\n\n return proxy;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport simulateEvent from '../helpers/dom/dispatchEvent';\nimport documentFragmentToHTML from '../helpers/dom/documentFragmentToHTML';\nimport findUpAttribute from '../helpers/dom/findUpAttribute';\nimport findUpTag from '../helpers/dom/findUpTag';\nimport getCaretPosNew from '../helpers/dom/getCaretPosNew';\nimport getRichValueWithCaret from '../helpers/dom/getRichValueWithCaret';\nimport isInputEmpty from '../helpers/dom/isInputEmpty';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport RichInputHandler, {USING_BOMS} from '../helpers/dom/richInputHandler';\nimport selectElementContents from '../helpers/dom/selectElementContents';\nimport setInnerHTML, {setDirection} from '../helpers/dom/setInnerHTML';\nimport {MessageEntity} from '../layer';\nimport {i18n, LangPackKey, _i18n} from '../lib/langPack';\nimport {NULL_PEER_ID} from '../lib/mtproto/mtproto_config';\nimport mergeEntities from '../lib/richTextProcessor/mergeEntities';\nimport parseEntities from '../lib/richTextProcessor/parseEntities';\nimport wrapDraftText from '../lib/richTextProcessor/wrapDraftText';\nimport {createCustomFiller, CustomEmojiElement, CustomEmojiRendererElement, insertCustomFillers, renderEmojis} from '../lib/richTextProcessor/wrapRichText';\n\nexport async function insertRichTextAsHTML(input: HTMLElement, text: string, entities: MessageEntity[], wrappingForPeerId: PeerId) {\n const loadPromises: Promise<any>[] = [];\n const wrappingCustomEmoji = entities?.some((entity) => entity._ === 'messageEntityCustomEmoji');\n const renderer = wrappingCustomEmoji ? createCustomEmojiRendererForInput() : undefined;\n const fragment = wrapDraftText(text, {entities, wrappingForPeerId, loadPromises, customEmojiRenderer: renderer});\n const something = fragment.querySelectorAll<HTMLElement>('[contenteditable=\"false\"]');\n something.forEach((el) => {\n el.contentEditable = 'inherit';\n el.classList.add('pc');\n });\n\n loadPromises.length && await Promise.all(loadPromises);\n\n fragment.querySelectorAll<HTMLElement>('.input-selectable').forEach((el) => {\n el.prepend(createCustomFiller(true));\n });\n\n const richInputHandler = USING_BOMS ? RichInputHandler.getInstance() : undefined;\n // const restore = richInputHandler.prepareApplyingMarkdown();\n\n // fragment.querySelectorAll('.input-filler').forEach((el) => el.remove());\n\n // const fillers = Array.from(input.querySelectorAll<HTMLElement>('.input-filler')).map((el) => {\n // el.contentEditable = 'false';\n // return el;\n // });\n\n const customEmojiElements = Array.from(fragment.querySelectorAll<HTMLImageElement>('.custom-emoji-placeholder')).map((el) => {\n el.dataset.ces = '1';\n return (el as any).customEmojiElement as CustomEmojiElement;\n });\n\n const html = documentFragmentToHTML(fragment);\n renderer?.destroy();\n\n // console.log(html);\n\n const pre = getCaretPosNew(input);\n // console.log('pre', pre);\n let textNode: ChildNode, textNodeValue: string;\n if(pre.node) {\n // if(pre.node?.nodeValue === BOM && false) {\n // textNode = document.createTextNode(textNodeValue = BOM);\n // (pre.node.parentNode as any as ChildNode).after(textNode);\n // pre.selection.modify('extend', 'forward', 'character');\n // pre.selection.collapseToEnd();\n // }\n } else {\n const range = document.createRange();\n let node = input.lastChild;\n if(!node) {\n input.append(node /* = textNode */ = document.createTextNode(''));\n }\n\n range.setStartAfter(node);\n range.collapse(true);\n pre.selection.removeAllRanges();\n pre.selection.addRange(range);\n }\n\n // const fragmentLastChild = fragment.lastChild;\n\n // const s = document.createElement('span');\n // (node as ChildNode).replaceWith(s);\n // s.append(node);\n input.addEventListener('input', cancelEvent, {capture: true, once: true, passive: false});\n richInputHandler?.onBeforeInput({inputType: 'insertContent'});\n window.document.execCommand('insertHTML', false, html);\n Array.from(input.querySelectorAll<HTMLImageElement>('[data-ces]')).forEach((el, idx) => {\n delete el.dataset.ces;\n const customEmojiElement = customEmojiElements[idx];\n (el as any).customEmojiElement = customEmojiElement;\n customEmojiElement.placeholder = el;\n });\n // fillers.forEach((el) => {\n // el.contentEditable = 'inherit';\n // });\n input.querySelectorAll<HTMLElement>('.pc').forEach((el) => {\n el.contentEditable = 'false';\n });\n if(textNode) {\n const {nodeValue} = textNode;\n if(nodeValue === textNodeValue) {\n textNode.remove();\n } else {\n (textNode as CharacterData).replaceData(nodeValue.indexOf(textNodeValue), textNodeValue.length, '');\n }\n }\n // restore();\n richInputHandler?.removeExtraBOMs(input);\n simulateEvent(input, 'input');\n\n // if(textNode) {\n // const selection = document.getSelection();\n // const node = fragmentLastChild.nextSibling || fragmentLastChild;\n // const range = document.createRange();\n // range.setStartAfter(node);\n // range.collapse(true);\n // selection.removeAllRanges();\n // selection.addRange(range);\n // }\n\n // const after = getCaretPosNew(input);\n // console.log('after', after);\n // if(after.node?.nodeValue === BOM) {\n // const smth = findUpClassName(after.node.parentElement, 'input-something');\n // if(smth) {\n // const selection = document.getSelection();\n // const node = smth.nextSibling;\n // const range = document.createRange();\n // range.setStartAfter(node);\n // range.collapse(true);\n // selection.removeAllRanges();\n // selection.addRange(range);\n\n // // if(after.offset === 0) after.selection.modify('extend', 'forward', 'character');\n // // after.selection.modify('extend', 'forward', 'character');\n // // after.selection.collapseToEnd();\n // }\n // }\n\n // setCaretAt(fragmentLastChild.nextSibling);\n\n // console.log('ASD');\n}\n\nlet init = () => {\n document.addEventListener('paste', (e) => {\n const input = findUpAttribute(e.target, 'contenteditable=\"true\"');\n if(!input) {\n return;\n }\n\n const noLinebreaks = !!input.dataset.noLinebreaks;\n e.preventDefault();\n let text: string, entities: MessageEntity[];\n\n // @ts-ignore\n let plainText: string = (e.originalEvent || e).clipboardData.getData('text/plain');\n let usePlainText = true;\n\n // @ts-ignore\n let html: string = (e.originalEvent || e).clipboardData.getData('text/html') || plainText;\n\n const filterEntity = (e: MessageEntity) => e._ === 'messageEntityEmoji' || (e._ === 'messageEntityLinebreak' && !noLinebreaks);\n if(noLinebreaks) {\n const regExp = /[\\r\\n]/g;\n plainText = plainText.replace(regExp, '');\n html = html.replace(regExp, '');\n }\n\n const peerId = (input.dataset.peerId || NULL_PEER_ID).toPeerId();\n if(html.trim()) {\n // console.log(html.replace(/ (style|class|id)=\".+?\"/g, ''));\n\n html = html.replace(/<style([\\s\\S]*)<\\/style>/, '');\n html = html.replace(/<!--([\\s\\S]*)-->/, '');\n html = html.replace('<br class=\"Apple-interchange-newline\">', '');\n\n const match = html.match(/<body>([\\s\\S]*)<\\/body>/);\n if(match) {\n html = match[1].trim();\n }\n\n // const s = cleanHTML(html, true) as NodeList;\n // console.log(s);\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n const span = doc.body || document.createElement('body');\n\n // const span: HTMLElement = document.createElement('span');\n // span.innerHTML = html;\n // span.append(...Array.from(s));\n\n let curChild = span.firstChild;\n while(curChild) { // * fix whitespace between elements like <p>asd</p>\\n<p>zxc</p>\n const nextSibling = curChild.nextSibling;\n if(curChild.nodeType === curChild.TEXT_NODE) {\n if(!curChild.nodeValue.trim()) {\n curChild.remove();\n }\n }\n\n curChild = nextSibling;\n }\n\n const richValue = getRichValueWithCaret(span, true, false);\n\n const canWrapCustomEmojis = !!peerId;\n if(!canWrapCustomEmojis) {\n richValue.entities = richValue.entities.filter((entity) => entity._ !== 'messageEntityCustomEmoji');\n }\n\n /* if(false) */ { // * fix extra new lines appearing from <p> (can have them from some sources, like macOS Terminal)\n const lines = richValue.value.split('\\n');\n let textLength = 0;\n for(let lineIndex = 0; lineIndex < lines.length; ++lineIndex) {\n const line = lines[lineIndex];\n textLength += line.length;\n\n const index = textLength;\n if(plainText[index] !== '\\n' && lineIndex !== (lines.length - 1)) {\n const nextLine = lines.splice(lineIndex + 1, 1)[0];\n lines[lineIndex] = line + nextLine;\n\n // fix entities\n richValue.entities.forEach((entity) => {\n if(entity.offset >= index) {\n entity.offset -= 1;\n }\n });\n\n textLength += nextLine.length;\n }\n\n textLength += 1;\n }\n\n const correctedText = lines.join('\\n');\n richValue.value = correctedText;\n }\n\n const richTextLength = richValue.value.replace(/\\s/g, '').length;\n const plainTextLength = plainText.replace(/\\s/g, '').length;\n if(richTextLength === plainTextLength ||\n richValue.entities.find((entity) => entity._ === 'messageEntityCustomEmoji')) {\n text = richValue.value;\n entities = richValue.entities;\n usePlainText = false;\n\n let entities2 = parseEntities(text);\n entities2 = entities2.filter(filterEntity);\n mergeEntities(entities, entities2);\n }\n\n // console.log('usePlainText', usePlainText);\n }\n\n if(usePlainText) {\n text = plainText;\n entities = parseEntities(text);\n entities = entities.filter(filterEntity);\n }\n\n insertRichTextAsHTML(input, text, entities, peerId);\n });\n\n init = null;\n};\n\n// ! it doesn't respect symbols other than strongs\n/* const checkAndSetRTL = (input: HTMLElement) => {\n //const isEmpty = isInputEmpty(input);\n //console.log('input', isEmpty);\n\n //const char = [...getRichValue(input)][0];\n const char = (input instanceof HTMLInputElement ? input.value : input.innerText)[0];\n let direction = 'ltr';\n if(char && checkRTL(char)) {\n direction = 'rtl';\n }\n\n //console.log('RTL', direction, char);\n\n input.style.direction = direction;\n}; */\n\nexport enum InputState {\n Neutral = 0,\n Valid = 1,\n Error = 2\n};\n\nexport type InputFieldOptions = {\n placeholder?: LangPackKey,\n label?: LangPackKey,\n labelOptions?: any[],\n labelText?: string | DocumentFragment,\n name?: string,\n maxLength?: number,\n showLengthOn?: number,\n plainText?: true,\n required?: boolean,\n canBeEdited?: boolean,\n validate?: () => boolean,\n inputMode?: 'tel' | 'numeric',\n withLinebreaks?: boolean,\n autocomplete?: string\n};\n\nfunction createCustomEmojiRendererForInput() {\n const renderer = CustomEmojiRendererElement.create({\n wrappingDraft: true,\n isSelectable: true\n });\n return renderer;\n}\n\nfunction processCustomEmojisInInput(input: HTMLElement) {\n const customEmojiElements = Array.from(input.querySelectorAll<CustomEmojiElement | HTMLElement>('.custom-emoji, .custom-emoji-placeholder'));\n let renderer = input.querySelector<CustomEmojiRendererElement>('.custom-emoji-renderer');\n if(!renderer && customEmojiElements.length) {\n renderer = createCustomEmojiRendererForInput();\n input.prepend(renderer);\n } else if(renderer && !customEmojiElements.length) {\n renderer.remove();\n return;\n }\n\n if(!renderer) {\n return;\n }\n\n const customEmojis: Parameters<CustomEmojiRendererElement['add']>[0] = new Map();\n customEmojiElements.forEach((element) => {\n const customEmojiElement = element instanceof CustomEmojiElement ? element : (element as any).customEmojiElement as CustomEmojiElement;\n const {docId} = customEmojiElement;\n let set = customEmojis.get(docId);\n if(!set) {\n customEmojis.set(docId, set = new Set());\n }\n\n set.add(customEmojiElement);\n });\n\n for(const [docId, customEmojiElements] of customEmojis) {\n let hasSet = renderer.customEmojis.get(docId);\n if(hasSet) {\n for(const customEmojiElement of hasSet) {\n if(!customEmojiElements.has(customEmojiElement)) {\n customEmojiElement.destroy();\n }\n }\n } else {\n hasSet = new Set();\n }\n\n for(const customEmojiElement of customEmojiElements) {\n if(!hasSet.has(customEmojiElement)) {\n customEmojiElement.connectedCallback();\n }\n }\n }\n\n renderer.add(customEmojis, false);\n renderer.forceRender();\n}\n\nexport default class InputField {\n public container: HTMLElement;\n public input: HTMLElement;\n public label: HTMLLabelElement;\n\n public originalValue: string;\n\n public required: boolean;\n public validate: () => boolean;\n\n constructor(public options: InputFieldOptions = {}) {\n this.container = document.createElement('div');\n this.container.classList.add('input-field');\n\n this.required = options.required;\n this.validate = options.validate;\n\n if(options.maxLength !== undefined && options.showLengthOn === undefined) {\n options.showLengthOn = Math.min(40, Math.round(options.maxLength / 3));\n }\n\n const {placeholder, maxLength, showLengthOn, name, plainText, canBeEdited = true, autocomplete} = options;\n const label = options.label || options.labelText;\n\n const onInputCallbacks: Array<() => void> = [];\n let input: HTMLElement;\n if(!plainText) {\n if(init) {\n init();\n }\n\n this.container.innerHTML = `<div class=\"input-field-input\"></div>`;\n\n input = this.container.firstElementChild as HTMLElement;\n input.contentEditable = '' + !!canBeEdited;\n // const observer = new MutationObserver(() => {\n // //checkAndSetRTL(input);\n\n // if(processInput) {\n // processInput();\n // }\n // });\n\n RichInputHandler.getInstance();\n\n input.addEventListener('mousedown', (e) => {\n const selection = document.getSelection();\n if(!selection.isCollapsed) {\n return;\n }\n\n const placeholder = findUpTag(e.target, 'IMG');\n if(!placeholder) {\n return;\n }\n\n const rect = placeholder.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const focusOnNext = e.clientX >= centerX;\n\n const range = document.createRange();\n range.setStartAfter(focusOnNext ? placeholder : placeholder.previousSibling ?? placeholder);\n selection.removeAllRanges();\n selection.addRange(range);\n });\n\n onInputCallbacks.push(() => {\n // console.log('input');\n // return;\n // * because if delete all characters there will br left\n if(isInputEmpty(input)) {\n // const textNode = Array.from(input.childNodes).find((node) => node.nodeType === node.TEXT_NODE) || document.createTextNode('');\n input.replaceChildren();\n // input.append(document.createTextNode('')); // need first text node to support history stack\n }\n\n // const fillers = Array.from(input.querySelectorAll('.emoji-filler')) as HTMLElement[];\n // fillers.forEach((filler) => {\n // const textContent = filler.textContent;\n // if(textContent === BOM) {\n // return;\n // }\n\n // if(textContent) {\n\n // } else {\n // let curChild = filler.firstChild;\n // while(curChild) {\n // curChild = curChild.nextSibling;\n // }\n // }\n\n // filler.classList.remove('emoji-filler');\n // });\n\n // Array.from(input.querySelectorAll('br, span:empty')).forEach((el) => {\n // const parentElement = el.parentElement;\n // (parentElement === input ? el : parentElement).remove();\n // });\n USING_BOMS && Array.from(input.querySelectorAll('br:not(.br-not-br)')).forEach((el) => {\n // const parentElement = el.parentElement;\n el.remove();\n // if(!parentElement.children.length && !parentElement.textContent) {\n // parentElement.textContent = '';\n // }\n });\n\n insertCustomFillers(Array.from(input.querySelectorAll('.input-something')));\n\n processCustomEmojisInInput(input);\n\n // .forEach((el) => el.remove());\n });\n\n // ! childList for paste first symbol\n // observer.observe(input, {characterData: true, childList: true, subtree: true});\n } else {\n this.container.innerHTML = `\n <input type=\"text\" ${name ? `name=\"${name}\"` : ''} autocomplete=\"${autocomplete ?? 'off'}\" ${label ? 'required=\"\"' : ''} class=\"input-field-input\">\n `;\n\n input = this.container.firstElementChild as HTMLElement;\n // input.addEventListener('input', () => checkAndSetRTL(input));\n }\n\n setDirection(input);\n\n if(options.inputMode) {\n input.inputMode = options.inputMode;\n }\n\n if(placeholder) {\n _i18n(input, placeholder, undefined, 'placeholder');\n }\n\n if(label || placeholder) {\n const border = document.createElement('div');\n border.classList.add('input-field-border');\n this.container.append(border);\n }\n\n if(label) {\n this.label = document.createElement('label');\n this.setLabel();\n this.container.append(this.label);\n }\n\n if(maxLength) {\n const labelEl = this.container.lastElementChild as HTMLLabelElement;\n let showingLength = false;\n\n const onInput = () => {\n const wasError = input.classList.contains('error');\n // * https://stackoverflow.com/a/54369605 #2 to count emoji as 1 symbol\n const inputLength = plainText ? (input as HTMLInputElement).value.length : [...getRichValueWithCaret(input, false, false).value].length;\n const diff = maxLength - inputLength;\n const isError = diff < 0;\n input.classList.toggle('error', isError);\n\n // this.onLengthChange && this.onLengthChange(inputLength, isError);\n\n if(isError || diff <= showLengthOn) {\n this.setLabel();\n labelEl.append(` (${maxLength - inputLength})`);\n if(!showingLength) showingLength = true;\n } else if((wasError && !isError) || showingLength) {\n this.setLabel();\n showingLength = false;\n }\n };\n\n onInputCallbacks.push(onInput);\n }\n\n const noLinebreaks = !options.withLinebreaks;\n if(noLinebreaks && !plainText) {\n input.dataset.noLinebreaks = '1';\n input.addEventListener('keypress', (e) => {\n if(e.key === 'Enter') {\n e.preventDefault();\n return false;\n }\n });\n }\n\n if(onInputCallbacks.length) {\n input.addEventListener('input', () => {\n onInputCallbacks.forEach((callback) => callback());\n });\n }\n\n this.input = input;\n }\n\n public select() {\n if(!this.value) { // * avoid selecting whole empty field on iOS devices\n return;\n }\n\n if(this.options.plainText) {\n (this.input as HTMLInputElement).select(); // * select text\n } else {\n selectElementContents(this.input);\n }\n }\n\n public setLabel() {\n this.label.textContent = '';\n if(this.options.labelText) {\n setInnerHTML(this.label, this.options.labelText);\n } else {\n this.label.append(i18n(this.options.label, this.options.labelOptions));\n }\n }\n\n get value(): string {\n return this.options.plainText ? (this.input as HTMLInputElement).value : getRichValueWithCaret(this.input, false, false).value;\n // return getRichValue(this.input);\n }\n\n set value(value: Parameters<typeof replaceContent>[1]) {\n this.setValueSilently(value, true);\n this.simulateInputEvent();\n }\n\n public simulateInputEvent() {\n simulateEvent(this.input, 'input');\n }\n\n public setValueSilently(value: Parameters<typeof replaceContent>[1], fromSet?: boolean) {\n if(this.options.plainText) {\n (this.input as HTMLInputElement).value = value as string;\n } else {\n replaceContent(this.input, value);\n processCustomEmojisInInput(this.input);\n }\n }\n\n public isChanged() {\n return this.value !== this.originalValue;\n }\n\n public isValid() {\n return !this.input.classList.contains('error') &&\n (!this.validate || this.validate()) &&\n (!this.required || !isInputEmpty(this.input));\n }\n\n public isValidToChange() {\n return this.isValid() && this.isChanged();\n }\n\n public setDraftValue(value = '', silent?: boolean) {\n if(!this.options.plainText) {\n value = documentFragmentToHTML(wrapDraftText(value));\n }\n\n if(silent) {\n this.setValueSilently(value, false);\n } else {\n this.value = value;\n }\n }\n\n public setOriginalValue(value: InputField['originalValue'] = '', silent?: boolean) {\n this.originalValue = value;\n this.setDraftValue(value, silent);\n }\n\n public setState(state: InputState, label?: LangPackKey) {\n if(label) {\n this.label.textContent = '';\n this.label.append(i18n(label, this.options.labelOptions));\n } else {\n this.setLabel();\n }\n\n this.input.classList.toggle('error', !!(state & InputState.Error));\n this.input.classList.toggle('valid', !!(state & InputState.Valid));\n }\n\n public setError(label?: LangPackKey) {\n this.setState(InputState.Error, label);\n }\n}\n","// https://stackoverflow.com/a/6150060\nexport default function selectElementContents(el: HTMLElement) {\n const range = document.createRange();\n range.selectNodeContents(el);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {USING_BOMS} from '../helpers/dom/richInputHandler';\nimport BOM from '../helpers/string/bom';\nimport {_i18n} from '../lib/langPack';\nimport InputField, {InputFieldOptions} from './inputField';\nimport SetTransition from './singleTransition';\n\nconst USELESS_REG_EXP = new RegExp(`(<span>${BOM}</span>)|(<br\\/?>)`, 'g');\n\nexport default class InputFieldAnimated extends InputField {\n public inputFake: HTMLElement;\n public onChangeHeight: (height: number) => void;\n\n // public onLengthChange: (length: number, isOverflow: boolean) => void;\n // protected wasInputFakeClientHeight: number;\n // protected showScrollDebounced: () => void;\n\n constructor(options?: InputFieldOptions) {\n super(options);\n\n this.input.addEventListener('input', () => {\n this.updateInnerHTML();\n this.onFakeInput();\n });\n\n if(options.placeholder) {\n _i18n(this.inputFake, options.placeholder, undefined, 'placeholder');\n }\n\n this.input.classList.add('scrollable', 'scrollable-y', 'no-scrollbar');\n // this.wasInputFakeClientHeight = 0;\n // this.showScrollDebounced = debounce(() => this.input.classList.remove('no-scrollbar'), 150, false, true);\n this.inputFake = document.createElement('div');\n // this.inputFake.contentEditable = 'true';\n this.inputFake.contentEditable = 'true';\n this.inputFake.tabIndex = -1;\n this.inputFake.className = this.input.className + ' input-field-input-fake';\n }\n\n public onFakeInput(setHeight = true, noAnimation?: boolean) {\n const {scrollHeight: newHeight/* , clientHeight */} = this.inputFake;\n /* if(this.wasInputFakeClientHeight && this.wasInputFakeClientHeight !== clientHeight) {\n this.input.classList.add('no-scrollbar'); // ! в сафари может вообще не появиться скролл после анимации, так как ему нужен полный reflow блока с overflow.\n this.showScrollDebounced();\n } */\n\n noAnimation ??= !this.input.isContentEditable;\n\n const currentHeight = +this.input.style.height.replace('px', '');\n if(currentHeight === newHeight) {\n return;\n }\n\n const TRANSITION_DURATION_FACTOR = 50;\n const transitionDuration = noAnimation ? 0 : Math.round(\n TRANSITION_DURATION_FACTOR * Math.log(Math.abs(newHeight - currentHeight))\n );\n\n // this.wasInputFakeClientHeight = clientHeight;\n this.input.style.transitionDuration = `${transitionDuration}ms`;\n\n if(setHeight) {\n this.onChangeHeight?.(newHeight);\n this.input.style.height = newHeight ? newHeight + 'px' : '';\n }\n\n const className = 'is-changing-height';\n SetTransition({\n element: this.input,\n className,\n forwards: true,\n duration: transitionDuration,\n onTransitionEnd: () => {\n this.input.classList.remove(className);\n }\n });\n }\n\n protected updateInnerHTML(innerHTML = this.input.innerHTML) {\n innerHTML = innerHTML.replace(/<custom-emoji-renderer-element.+\\/custom-emoji-renderer-element>/, '')\n .replace(/(<custom-emoji-element.+?>).+?\\/custom-emoji-element>/g, '$1</custom-emoji-element>')\n\n if(USING_BOMS) {\n innerHTML = innerHTML.replace(USELESS_REG_EXP, '');\n }\n\n this.inputFake.innerHTML = innerHTML;\n }\n\n public setValueSilently(value: Parameters<InputField['setValueSilently']>[0], fromSet?: boolean) {\n super.setValueSilently(value, fromSet);\n\n this.updateInnerHTML();\n if(!fromSet) {\n this.onFakeInput();\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// import { getRichValue } from \"../helpers/dom\";\nimport {LangPackKey} from '../lib/langPack';\nimport InputField from './inputField';\n\nexport default class InputSearch {\n public container: HTMLElement;\n public input: HTMLElement;\n public inputField: InputField;\n public clearBtn: HTMLElement;\n\n public prevValue = '';\n public timeout = 0;\n public onChange: (value: string) => void;\n public onClear: () => void;\n\n constructor(placeholder: LangPackKey, onChange?: (value: string) => void) {\n this.inputField = new InputField({\n placeholder,\n plainText: true\n });\n\n this.container = this.inputField.container;\n this.container.classList.remove('input-field');\n this.container.classList.add('input-search');\n\n this.onChange = onChange;\n\n this.input = this.inputField.input;\n this.input.classList.add('input-search-input');\n\n const searchIcon = document.createElement('i');\n searchIcon.classList.add('tgico', 'tgico-search');\n\n this.clearBtn = document.createElement('i');\n this.clearBtn.classList.add('tgico', 'btn-icon', 'tgico-close');\n\n this.input.addEventListener('input', this.onInput);\n this.clearBtn.addEventListener('click', this.onClearClick);\n\n this.container.append(searchIcon, this.clearBtn);\n }\n\n onInput = () => {\n if(!this.onChange) return;\n\n const value = this.value;\n\n // this.input.classList.toggle('is-empty', !value.trim());\n\n if(value !== this.prevValue) {\n this.prevValue = value;\n clearTimeout(this.timeout);\n this.timeout = window.setTimeout(() => {\n this.onChange(value);\n }, 200);\n }\n };\n\n onClearClick = () => {\n this.value = '';\n this.onChange && this.onChange('');\n this.onClear && this.onClear();\n };\n\n get value() {\n return this.inputField.value;\n }\n\n set value(value: string) {\n this.prevValue = value;\n clearTimeout(this.timeout);\n this.inputField.value = value;\n }\n\n public remove() {\n clearTimeout(this.timeout);\n this.input.removeEventListener('input', this.onInput);\n this.clearBtn.removeEventListener('click', this.onClearClick);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport VisibilityIntersector, {OnVisibilityChangeItem} from './visibilityIntersector';\nimport findAndSpliceAll from '../helpers/array/findAndSpliceAll';\nimport findAndSplice from '../helpers/array/findAndSplice';\nimport LazyLoadQueueIntersector, {LazyLoadElement} from './lazyLoadQueueIntersector';\nimport useHeavyAnimationCheck from '../hooks/useHeavyAnimationCheck';\n\nexport default class LazyLoadQueue extends LazyLoadQueueIntersector {\n constructor(parallelLimit?: number, ignoreHeavyAnimation?: boolean) {\n super(parallelLimit);\n\n this.intersector = new VisibilityIntersector(this.onVisibilityChange);\n\n !ignoreHeavyAnimation && useHeavyAnimationCheck(() => {\n this.lock();\n }, () => {\n this.unlockAndRefresh();\n });\n }\n\n private onVisibilityChange = ({target, visible}: OnVisibilityChangeItem) => {\n // if(DEBUG) {\n // this.log('isIntersecting', target, visible);\n // }\n\n // if visible - will move to the end of visible arary\n findAndSpliceAll(this.queue, (i) => i.div === target).forEach((item) => {\n if(visible) {\n item.wasSeen = true;\n }\n\n item.visible = visible;\n const index = this.queue.findIndex((item) => !item.visible);\n this.queue.splice(Math.max(0, index), 0, item);\n });\n\n this.setProcessQueueTimeout();\n };\n\n protected getItem() {\n return findAndSplice(this.queue, (item) => item.wasSeen);\n }\n\n public async processItem(item: LazyLoadElement) {\n await super.processItem(item);\n this.intersector.unobserve(item.div);\n }\n\n protected addElement(method: 'push' | 'unshift', el: LazyLoadElement) {\n const inserted = super.addElement(method, el);\n\n if(!inserted) return false;\n\n this.observe(el);\n /* if(el.wasSeen) {\n this.processQueue(el);\n } else */\n el.wasSeen ??= false;\n\n return true;\n }\n\n public setAllSeen() {\n this.queue.forEach((item) => {\n item.wasSeen = true;\n });\n\n this.setProcessQueueTimeout();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport findAndSpliceAll from '../helpers/array/findAndSpliceAll';\nimport LazyLoadQueueBase, {LazyLoadElementBase} from './lazyLoadQueueBase';\nimport VisibilityIntersector from './visibilityIntersector';\n\nexport type LazyLoadElement = Omit<LazyLoadElementBase, 'load'> & {\n load: (target?: HTMLElement) => Promise<any>,\n div: HTMLElement\n wasSeen?: boolean,\n visible?: boolean\n};\n\nexport default class LazyLoadQueueIntersector extends LazyLoadQueueBase {\n protected queue: Array<LazyLoadElement> = [];\n protected inProcess: Set<LazyLoadElement> = new Set();\n\n public intersector: VisibilityIntersector;\n protected intersectorTimeout: number;\n\n constructor(parallelLimit?: number) {\n super(parallelLimit);\n }\n\n public lock() {\n super.lock();\n this.intersector.lock();\n }\n\n public unlock() {\n super.unlock();\n this.intersector.unlock();\n }\n\n public unlockAndRefresh() {\n super.unlock();\n this.intersector.unlockAndRefresh();\n }\n\n public clear() {\n super.clear();\n this.intersector.disconnect();\n }\n\n public refresh() {\n this.intersector.refresh();\n }\n\n protected loadItem(item: LazyLoadElement) {\n return item.load(item.div);\n }\n\n protected addElement(method: 'push' | 'unshift', el: LazyLoadElement) {\n const item = this.queue.find((i) => i.div === el.div && i.load === el.load);\n if(item) {\n return false;\n } else {\n for(const item of this.inProcess) {\n if(item.div === el.div && item.load === el.load) {\n return false;\n }\n }\n }\n\n this.queue[method](el);\n return true;\n }\n\n protected setProcessQueueTimeout() {\n this.intersectorTimeout ??= window.setTimeout(() => {\n this.intersectorTimeout = undefined;\n this.processQueue();\n }, 0);\n }\n\n public push(el: LazyLoadElement) {\n super.push(el);\n }\n\n public unshift(el: LazyLoadElement) {\n super.unshift(el);\n }\n\n public delete(el: Omit<LazyLoadElement, 'load'>) {\n findAndSpliceAll(this.queue, (i) => i.div === el.div);\n this.unobserve(el);\n }\n\n public observe(el: LazyLoadElement) {\n this.intersector.observe(el.div);\n }\n\n public unobserve(el: Omit<LazyLoadElement, 'load'>) {\n this.intersector.unobserve(el.div);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {GrabEvent} from '../helpers/dom/attachGrabListeners';\nimport appMediaPlaybackController from './appMediaPlaybackController';\nimport RangeSelector from './rangeSelector';\n\nexport default class MediaProgressLine extends RangeSelector {\n protected filledLoad: HTMLDivElement;\n\n protected progressRAF: number;\n\n protected media: HTMLMediaElement;\n protected streamable: boolean;\n\n // protected lastOnPlayTime: number;\n // protected lastOnPlayCurrentTime: number;\n\n constructor(protected options: {\n withTransition?: boolean,\n useTransform?: boolean,\n onSeekStart?: () => void,\n onSeekEnd?: () => void\n } = {}) {\n super({\n step: 1000 / 60 / 1000,\n min: 0,\n max: 1,\n withTransition: options.withTransition,\n useTransform: options.useTransform\n }, 0);\n }\n\n public setMedia({\n media,\n streamable,\n duration\n }: {\n media: HTMLMediaElement,\n streamable?: boolean,\n duration?: number\n }) {\n if(this.media) {\n this.removeListeners();\n }\n\n if(streamable && !this.filledLoad) {\n this.filledLoad = document.createElement('div');\n this.filledLoad.classList.add('progress-line__filled', 'progress-line__loaded');\n this.container.prepend(this.filledLoad);\n // this.setLoadProgress();\n } else if(this.filledLoad) {\n this.filledLoad.classList.toggle('hide', !streamable);\n }\n\n this.media = media;\n this.streamable = streamable;\n if(!media.paused || media.currentTime > 0) {\n this.onPlay();\n }\n\n let wasPlaying = false;\n this.setSeekMax(duration);\n this.setListeners();\n this.setHandlers({\n onMouseDown: () => {\n wasPlaying = !this.media.paused;\n wasPlaying && this.media.pause();\n this.options?.onSeekStart?.();\n },\n\n onMouseUp: (e) => {\n // cancelEvent(e.event);\n wasPlaying && this.media.play();\n this.options?.onSeekEnd?.();\n }\n });\n }\n\n protected onLoadedData = () => {\n this.setSeekMax();\n };\n\n protected onEnded = () => {\n this.setProgress();\n };\n\n protected onPlay = () => {\n const r = () => {\n this.setProgress();\n\n this.progressRAF = this.media.paused ? undefined : window.requestAnimationFrame(r);\n };\n\n if(this.progressRAF) {\n window.cancelAnimationFrame(this.progressRAF);\n this.progressRAF = undefined;\n }\n\n if(this.streamable) {\n this.setLoadProgress();\n }\n\n // this.lastOnPlayTime = Date.now();\n // this.lastOnPlayCurrentTime = this.media.currentTime;\n r();\n // this.progressRAF = window.requestAnimationFrame(r);\n };\n\n protected onTimeUpdate = () => {\n if(this.media.paused) {\n this.setProgress();\n\n if(this.streamable) {\n this.setLoadProgress();\n }\n }\n };\n\n protected onProgress = (e: Event) => {\n this.setLoadProgress();\n };\n\n protected scrub(e: GrabEvent) {\n const scrubTime = super.scrub(e);\n this.media.currentTime = scrubTime;\n return scrubTime;\n }\n\n protected setLoadProgress() {\n if(appMediaPlaybackController.isSafariBuffering(this.media)) return;\n const buf = this.media.buffered;\n const numRanges = buf.length;\n\n const currentTime = this.media.currentTime;\n let nearestStart = 0, end = 0;\n for(let i = 0; i < numRanges; ++i) {\n const start = buf.start(i);\n if(currentTime >= start && start >= nearestStart) {\n nearestStart = start;\n end = buf.end(i);\n }\n\n // console.log('onProgress range:', i, buf.start(i), buf.end(i), this.media);\n }\n\n // console.log('onProgress correct range:', nearestStart, end, this.media);\n\n const percents = this.max ? end / this.max : 0;\n this.filledLoad.style.width = (percents * 100) + '%';\n // this.filledLoad.style.transform = 'scaleX(' + percents + ')';\n }\n\n protected setSeekMax(duration?: number) {\n const realDuration = this.media.duration || 0;\n if(duration === undefined || realDuration) duration = realDuration;\n if(this.max = duration) {\n this.seek.setAttribute('max', '' + this.max);\n } else {\n this.media.addEventListener('loadeddata', this.onLoadedData);\n }\n }\n\n public setProgress() {\n if(appMediaPlaybackController.isSafariBuffering(this.media)) return;\n\n // fix jumping progress on play\n // let currentTime: number;\n // const diff = (Date.now() - this.lastOnPlayTime) / 1000;\n // if(!this.media.paused && this.lastOnPlayTime && diff <= 1) {\n // currentTime = this.lastOnPlayCurrentTime + diff;\n // } else {\n // currentTime = this.media.currentTime;\n // }\n\n const currentTime = this.media.currentTime;\n super.setProgress(currentTime);\n }\n\n public setListeners() {\n super.setListeners();\n this.media.addEventListener('ended', this.onEnded);\n this.media.addEventListener('play', this.onPlay);\n this.media.addEventListener('pause', this.onTimeUpdate);\n this.media.addEventListener('timeupdate', this.onTimeUpdate);\n this.streamable && this.media.addEventListener('progress', this.onProgress);\n }\n\n public removeListeners() {\n super.removeListeners();\n\n if(this.media) {\n this.media.removeEventListener('loadeddata', this.onLoadedData);\n this.media.removeEventListener('ended', this.onEnded);\n this.media.removeEventListener('play', this.onPlay);\n this.media.removeEventListener('pause', this.onTimeUpdate);\n this.media.removeEventListener('timeupdate', this.onTimeUpdate);\n this.streamable && this.media.removeEventListener('progress', this.onProgress);\n }\n\n if(this.progressRAF) {\n window.cancelAnimationFrame(this.progressRAF);\n this.progressRAF = undefined;\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {FontFamily, FontSize, FontWeight} from '../config/font';\nimport getTextWidth from '../helpers/canvas/getTextWidth';\nimport mediaSizes from '../helpers/mediaSizes';\nimport clamp from '../helpers/number/clamp';\nimport {fastRaf} from '../helpers/schedulers';\n\n// Thanks to https://stackoverflow.com/a/49349813\n\n/**\n * Attibute modifier to create middle ellipsis\n * When the attribute value is left blank the ellipsis will be in the middle\n * When positive the attribute value will be used as a percentage\n * When negative the attribute value will be used as character index counted from the end\n * @example\n * <div data-middle-ellipsis>A Javascript solution to middle ellipsis</div>\n * <div data-middle-ellipsis=\"20\">A Javascript solution to middle ellipsis</div>\n * <div data-middle-ellipsis=\"-3\">A Javascript solution to middle ellipsis</div>\n */\nconst ellipsis = '…';\nconst map: Map<HTMLElement, {\n text: string,\n textLength: number,\n from: number,\n multiplier: number,\n font: string,\n textWidth: number,\n elementWidth: number\n}> = new Map();\n\nconst testQueue: Set<HTMLElement> = new Set();\nconst fontSize = '16px';\nlet pendingTest = false;\n\nfunction setTestQueue() {\n if(pendingTest) {\n return;\n }\n\n pendingTest = true;\n fastRaf(() => {\n pendingTest = false;\n testQueueElements();\n });\n}\n\nfunction testQueueElements() {\n testQueue.forEach(testElement);\n testQueue.clear();\n}\n\nwindow.addEventListener('resize', () => {\n for(const [key] of map) {\n testQueue.add(key);\n }\n\n setTestQueue();\n}, {capture: true, passive: true});\n\nfunction getElementWidth(element: HTMLElement) {\n const getSize = (element as any).getSize;\n if(getSize) {\n return getSize();\n }\n\n const type = element.dataset.sizeType;\n if(type) {\n const mediaSize = mediaSizes.active;\n // @ts-ignore\n const size: MediaSize = mediaSize[type];\n return size.width;\n }\n\n return element.getBoundingClientRect().width;\n}\n\nfunction testElement(element: HTMLElement) {\n // const perf = performance.now();\n // do not recalculate variables a second time\n let mapped = map.get(element);\n const firstTime = !mapped;\n\n let {text, textLength, from, multiplier, font, textWidth, elementWidth} = mapped || {};\n // console.log('[MEE] testElement got mapped', mapped);\n\n if(firstTime) {\n text = element.textContent;\n textLength = text.length;\n from = /* parseFloat(element.getAttribute(attributeName)) || */50;\n multiplier = from > 0 && from / 100;\n\n let fontSize = element.dataset.fontSize;\n if(fontSize && +fontSize) fontSize += 'px';\n // const perf = performance.now();\n font = `${element.dataset.fontWeight || FontWeight} ${fontSize || FontSize} ${FontFamily}`;\n /* const computedStyle = window.getComputedStyle(elm, null);\n font = `${computedStyle.getPropertyValue('font-weight')} ${computedStyle.getPropertyValue('font-size')} ${computedStyle.getPropertyValue('font-family')}`; */\n // console.log('testMiddleEllipsis get computed style:', performance.now() - perf, font);\n\n textWidth = getTextWidth(text, font);\n // const perf = performance.now();\n elementWidth = getElementWidth(element);\n // console.log('testMiddleEllipsis get offsetWidth:', performance.now() - perf, font);\n mapped = {text, textLength, from, multiplier, font, textWidth, elementWidth};\n map.set(element, mapped);\n\n // console.log('[MEE] testElement map set', element);\n }\n\n const newElementWidth = getElementWidth(element);\n const widthChanged = firstTime || elementWidth !== newElementWidth;\n !firstTime && widthChanged && (mapped.elementWidth = elementWidth = newElementWidth);\n\n if(widthChanged) {\n if(textWidth > elementWidth) {\n element.setAttribute('title', text);\n let smallerText = text;\n let smallerWidth = elementWidth;\n while(smallerText.length > 3) {\n const smallerTextLength = smallerText.length;\n const half = multiplier &&\n clamp(multiplier * smallerTextLength << 0, 1, smallerTextLength - 2) ||\n Math.max(smallerTextLength + from - 1, 1);\n const half1 = smallerText.substr(0, half).replace(/\\s*$/, '');\n const half2 = smallerText.substr(half + 1).replace(/^\\s*/, '');\n smallerText = half1 + half2;\n smallerWidth = getTextWidth(smallerText + ellipsis, font);\n if(smallerWidth < elementWidth) {\n element.textContent = half1 + ellipsis + half2;\n break;\n }\n }\n\n // * set new width after cutting text\n mapped.elementWidth = getElementWidth(element);\n // mapped.textWidth = smallerWidth;\n } else {\n element.removeAttribute('title');\n }\n }\n\n // console.log('testMiddleEllipsis for element:', elm, performance.now() - perf);\n}\n\nexport class MiddleEllipsisElement extends HTMLElement {\n connectedCallback() {\n // console.log('[MEE]: connectedCallback before', map.has(this), testQueue.has(this), map.size, this.textContent, map);\n\n map.set(this, null);\n if(this.dataset.sizeType || (this as any).getSize) {\n testElement(this);\n } else {\n testQueue.add(this);\n setTestQueue();\n }\n // testElement(this);\n\n // console.log('[MEE]: connectedCallback after', map.has(this), map.size, testQueue.has(this), testQueue.size);\n }\n\n disconnectedCallback() {\n const deleted = map.delete(this);\n testQueue.delete(this);\n // console.log('[MEE]: disconnectedCallback', deleted, map.has(this), map.size, this.textContent, map);\n }\n}\n\ncustomElements.define('middle-ellipsis-element', MiddleEllipsisElement);\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport lottieLoader, {LottieLoader} from '../../lib/rlottie/lottieLoader';\nimport RLottiePlayer from '../../lib/rlottie/rlottiePlayer';\nimport PasswordInputField from '../passwordInputField';\n\nexport default class PasswordMonkey {\n public container: HTMLElement;\n public animation: RLottiePlayer;\n public needFrame = 0;\n protected loadPromise: ReturnType<LottieLoader['waitForFirstFrame']>;\n\n constructor(protected passwordInputField: PasswordInputField, protected size: number) {\n this.container = document.createElement('div');\n this.container.classList.add('media-sticker-wrapper');\n }\n\n public load() {\n if(this.loadPromise) return this.loadPromise;\n return this.loadPromise = lottieLoader.loadAnimationAsAsset({\n container: this.container,\n loop: false,\n autoplay: false,\n width: this.size,\n height: this.size,\n noCache: true\n // }, 'assets/img/TwoFactorSetupMonkeyClose.tgs').then((_animation) => {\n }, 'TwoFactorSetupMonkeyPeek').then((_animation) => {\n // return;\n this.animation = _animation;\n this.animation.addEventListener('enterFrame', currentFrame => {\n // console.log('enterFrame', currentFrame, this.needFrame);\n\n if((this.animation.direction === 1 && currentFrame >= this.needFrame) ||\n (this.animation.direction === -1 && currentFrame <= this.needFrame)) {\n this.animation.setSpeed(1);\n this.animation.pause();\n }\n });\n\n this.passwordInputField.helpers.onVisibilityClickAdditional = () => {\n if(this.passwordInputField.helpers.passwordVisible) {\n this.animation.setDirection(1);\n this.animation.curFrame = 0;\n this.needFrame = 16;\n this.animation.play();\n } else {\n this.animation.setDirection(-1);\n this.animation.curFrame = 16;\n this.needFrame = 0;\n this.animation.play();\n }\n };\n\n return lottieLoader.waitForFirstFrame(_animation);\n });\n }\n\n public remove() {\n if(this.animation) {\n this.animation.remove();\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport InputField from '../inputField';\nimport lottieLoader from '../../lib/rlottie/lottieLoader';\nimport RLottiePlayer from '../../lib/rlottie/rlottiePlayer';\n\nexport default class TrackingMonkey {\n public container: HTMLElement;\n\n protected max = 45;\n protected needFrame = 0;\n\n protected animation: RLottiePlayer;\n protected idleAnimation: RLottiePlayer;\n\n protected loadPromise: Promise<any>;\n\n constructor(protected inputField: InputField, protected size: number) {\n this.container = document.createElement('div');\n this.container.classList.add('media-sticker-wrapper');\n\n const input = inputField.input;\n\n input.addEventListener('blur', () => {\n this.playAnimation(0);\n });\n\n input.addEventListener('input', (e) => {\n this.playAnimation(inputField.value.length);\n });\n\n /* codeInput.addEventListener('focus', () => {\n playAnimation(Math.max(codeInput.value.length, 1));\n }); */\n }\n\n // 1st symbol = frame 15\n // end symbol = frame 165\n public playAnimation(length: number) {\n if(!this.animation) return;\n\n length = Math.min(length, 30);\n let frame: number;\n if(length) {\n frame = Math.round(Math.min(this.max, length) * (165 / this.max) + 11.33);\n\n if(this.idleAnimation) {\n this.idleAnimation.stop(true);\n this.idleAnimation.canvas[0].style.display = 'none';\n }\n\n this.animation.canvas[0].style.display = '';\n } else {\n /* const cb = (frameNo: number) => {\n if(frameNo <= 1) { */\n /* idleAnimation.play();\n idleAnimation.canvas.style.display = '';\n animation.canvas.style.display = 'none'; */\n /* animation.removeListener('enterFrame', cb);\n }\n };\n animation.addListener('enterFrame', cb); */\n\n frame = 0;\n }\n // animation.playSegments([1, 2]);\n\n const direction = this.needFrame > frame ? -1 : 1;\n // console.log('keydown', length, frame, direction);\n\n this.animation.setDirection(direction);\n if(this.needFrame !== 0 && frame === 0) {\n this.animation.setSpeed(7);\n }\n /* let diff = Math.abs(needFrame - frame * direction);\n if((diff / 20) > 1) animation.setSpeed(diff / 20 | 0); */\n this.needFrame = frame;\n\n this.animation.play();\n\n /* animation.goToAndStop(15, true); */\n // animation.goToAndStop(length / max * );\n }\n\n public load() {\n if(this.loadPromise) return this.loadPromise;\n return this.loadPromise = Promise.all([\n lottieLoader.loadAnimationAsAsset({\n container: this.container,\n loop: true,\n autoplay: true,\n width: this.size,\n height: this.size\n }, 'TwoFactorSetupMonkeyIdle').then((animation) => {\n this.idleAnimation = animation;\n\n // ! animationIntersector will stop animation instantly\n if(!this.inputField.value.length) {\n animation.play();\n }\n\n return lottieLoader.waitForFirstFrame(animation);\n }),\n\n lottieLoader.loadAnimationAsAsset({\n container: this.container,\n loop: false,\n autoplay: false,\n width: this.size,\n height: this.size\n }, 'TwoFactorSetupMonkeyTracking').then((_animation) => {\n this.animation = _animation;\n\n if(!this.inputField.value.length) {\n this.animation.canvas[0].style.display = 'none';\n }\n\n this.animation.addEventListener('enterFrame', currentFrame => {\n // console.log('enterFrame', currentFrame, needFrame);\n // let currentFrame = Math.round(e.currentTime);\n\n if((this.animation.direction === 1 && currentFrame >= this.needFrame) ||\n (this.animation.direction === -1 && currentFrame <= this.needFrame)) {\n this.animation.setSpeed(1);\n this.animation.pause();\n }\n\n if(currentFrame === 0 && this.needFrame === 0) {\n // animation.curFrame = 0;\n\n if(this.idleAnimation) {\n this.idleAnimation.canvas[0].style.display = '';\n this.idleAnimation.play();\n this.animation.canvas[0].style.display = 'none';\n }\n }\n });\n // console.log(animation.getDuration(), animation.getDuration(true));\n\n return lottieLoader.waitForFirstFrame(_animation);\n })\n ]);\n }\n\n public remove() {\n if(this.animation) this.animation.remove();\n if(this.idleAnimation) this.idleAnimation.remove();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport InputField, {InputFieldOptions} from './inputField';\n\nexport class PasswordInputHelpers {\n public passwordVisible = false;\n public toggleVisible: HTMLElement;\n public onVisibilityClickAdditional: () => void;\n\n constructor(public container: HTMLElement, public input: HTMLInputElement) {\n input.type = 'password';\n input.setAttribute('required', '');\n input.name = 'notsearch_password';\n input.autocomplete = 'off';\n\n // * https://stackoverflow.com/a/35949954/6758968\n const stealthy = document.createElement('input');\n stealthy.classList.add('stealthy');\n stealthy.tabIndex = -1;\n stealthy.type = 'password';\n input.parentElement.prepend(stealthy);\n input.parentElement.insertBefore(stealthy.cloneNode(), input.nextSibling);\n\n /* if(IS_SAFARI && !IS_MOBILE_SAFARI) {\n input.setAttribute('readonly', '');\n input.addEventListener('focus', () => {\n input.removeAttribute('readonly');\n }, {once: true});\n } */\n\n const toggleVisible = this.toggleVisible = document.createElement('span');\n toggleVisible.classList.add('toggle-visible', 'tgico');\n\n container.classList.add('input-field-password');\n container.append(toggleVisible);\n\n toggleVisible.addEventListener('click', this.onVisibilityClick);\n toggleVisible.addEventListener('touchend', this.onVisibilityClick);\n }\n\n public onVisibilityClick = (e: Event) => {\n cancelEvent(e);\n this.passwordVisible = !this.passwordVisible;\n\n this.toggleVisible.classList.toggle('eye-hidden', this.passwordVisible);\n (this.input as HTMLInputElement).type = this.passwordVisible ? 'text' : 'password';\n this.onVisibilityClickAdditional && this.onVisibilityClickAdditional();\n };\n}\n\nexport default class PasswordInputField extends InputField {\n public helpers: PasswordInputHelpers;\n\n constructor(options: InputFieldOptions = {}) {\n super({\n plainText: true,\n ...options\n });\n\n this.helpers = new PasswordInputHelpers(this.container, this.input as HTMLInputElement);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_PARALLAX_SUPPORTED from '../environment/parallaxSupport';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport findAndSplice from '../helpers/array/findAndSplice';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport filterChatPhotosMessages from '../helpers/filterChatPhotosMessages';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport ListLoader from '../helpers/listLoader';\nimport {fastRaf} from '../helpers/schedulers';\nimport {Message, ChatFull, MessageAction, Photo} from '../layer';\nimport type {AppMessagesManager} from '../lib/appManagers/appMessagesManager';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport choosePhotoSize from '../lib/appManagers/utils/photos/choosePhotoSize';\nimport {openAvatarViewer} from './avatar';\nimport {putAvatar} from './putPhoto';\nimport Scrollable from './scrollable';\nimport SwipeHandler from './swipeHandler';\nimport wrapPhoto from './wrappers/photo';\n\nconst LOAD_NEAREST = 3;\n\nexport default class PeerProfileAvatars {\n private static BASE_CLASS = 'profile-avatars';\n private static SCALE = IS_PARALLAX_SUPPORTED ? 2 : 1;\n private static TRANSLATE_TEMPLATE = IS_PARALLAX_SUPPORTED ? `translate3d({x}, 0, -1px) scale(${PeerProfileAvatars.SCALE})` : 'translate({x}, 0)';\n public container: HTMLElement;\n public avatars: HTMLElement;\n public gradient: HTMLElement;\n public info: HTMLElement;\n public arrowPrevious: HTMLElement;\n public arrowNext: HTMLElement;\n private tabs: HTMLDivElement;\n private listLoader: ListLoader<Photo.photo['id'] | Message.messageService, Photo.photo['id'] | Message.messageService>;\n private peerId: PeerId;\n private intersectionObserver: IntersectionObserver;\n private loadCallbacks: Map<Element, () => void>;\n private listenerSetter: ListenerSetter;\n private swipeHandler: SwipeHandler;\n\n constructor(\n public scrollable: Scrollable,\n private managers: AppManagers\n ) {\n this.container = document.createElement('div');\n this.container.classList.add(PeerProfileAvatars.BASE_CLASS + '-container');\n\n this.avatars = document.createElement('div');\n this.avatars.classList.add(PeerProfileAvatars.BASE_CLASS + '-avatars');\n\n this.gradient = document.createElement('div');\n this.gradient.classList.add(PeerProfileAvatars.BASE_CLASS + '-gradient');\n\n this.info = document.createElement('div');\n this.info.classList.add(PeerProfileAvatars.BASE_CLASS + '-info');\n\n this.tabs = document.createElement('div');\n this.tabs.classList.add(PeerProfileAvatars.BASE_CLASS + '-tabs');\n\n this.arrowPrevious = document.createElement('div');\n this.arrowPrevious.classList.add(PeerProfileAvatars.BASE_CLASS + '-arrow', 'tgico-avatarprevious');\n\n /* const previousIcon = document.createElement('i');\n previousIcon.classList.add(PeerProfileAvatars.BASE_CLASS + '-arrow-icon', 'tgico-previous');\n this.arrowBack.append(previousIcon); */\n\n this.arrowNext = document.createElement('div');\n this.arrowNext.classList.add(PeerProfileAvatars.BASE_CLASS + '-arrow', PeerProfileAvatars.BASE_CLASS + '-arrow-next', 'tgico-avatarnext');\n\n /* const nextIcon = document.createElement('i');\n nextIcon.classList.add(PeerProfileAvatars.BASE_CLASS + '-arrow-icon', 'tgico-next');\n this.arrowNext.append(nextIcon); */\n\n this.container.append(this.avatars, this.gradient, this.info, this.tabs, this.arrowPrevious, this.arrowNext);\n\n this.loadCallbacks = new Map();\n this.listenerSetter = new ListenerSetter();\n\n const checkScrollTop = () => {\n if(this.scrollable.scrollTop !== 0) {\n this.scrollable.scrollIntoViewNew({\n element: this.scrollable.container.firstElementChild as HTMLElement,\n position: 'start'\n });\n return false;\n }\n\n return true;\n };\n\n const SWITCH_ZONE = 1 / 3;\n let cancel = false;\n let freeze = false;\n attachClickEvent(this.container, async(_e) => {\n if(freeze) {\n cancelEvent(_e);\n return;\n }\n\n if(cancel) {\n cancel = false;\n return;\n }\n\n if(!checkScrollTop()) {\n return;\n }\n\n const rect = this.container.getBoundingClientRect();\n\n // const e = (_e as TouchEvent).touches ? (_e as TouchEvent).touches[0] : _e as MouseEvent;\n const e = _e;\n const x = e.pageX;\n\n const clickX = x - rect.left;\n if((!this.listLoader.previous.length && !this.listLoader.next.length) ||\n (clickX > (rect.width * SWITCH_ZONE) && clickX < (rect.width - rect.width * SWITCH_ZONE))) {\n const peerId = this.peerId;\n\n const targets: {element: HTMLElement, item: Photo.photo['id'] | Message.messageService}[] = [];\n this.listLoader.previous.concat(this.listLoader.current, this.listLoader.next).forEach((item, idx) => {\n targets.push({\n element: /* null */this.avatars.children[idx] as HTMLElement,\n item\n });\n });\n\n const prevTargets = targets.slice(0, this.listLoader.previous.length);\n const nextTargets = targets.slice(this.listLoader.previous.length + 1);\n\n const target = this.avatars.children[this.listLoader.previous.length] as HTMLElement;\n freeze = true;\n openAvatarViewer(target, peerId, () => peerId === this.peerId, this.listLoader.current, prevTargets, nextTargets);\n freeze = false;\n } else {\n const centerX = rect.right - (rect.width / 2);\n const toRight = x > centerX;\n\n // this.avatars.classList.remove('no-transition');\n // fastRaf(() => {\n this.avatars.classList.add('no-transition');\n void this.avatars.offsetLeft; // reflow\n\n let distance: number;\n if(this.listLoader.index === 0 && !toRight) distance = this.listLoader.count - 1;\n else if(this.listLoader.index === (this.listLoader.count - 1) && toRight) distance = -(this.listLoader.count - 1);\n else distance = toRight ? 1 : -1;\n this.listLoader.go(distance);\n\n fastRaf(() => {\n this.avatars.classList.remove('no-transition');\n });\n // });\n }\n }, {listenerSetter: this.listenerSetter});\n\n const cancelNextClick = () => {\n cancel = true;\n document.body.addEventListener(IS_TOUCH_SUPPORTED ? 'touchend' : 'click', (e) => {\n cancel = false;\n }, {once: true});\n };\n\n let width = 0, x = 0, lastDiffX = 0, /* lastIndex = 0, */ minX = 0;\n const swipeHandler = this.swipeHandler = new SwipeHandler({\n element: this.avatars,\n onSwipe: (xDiff, yDiff) => {\n xDiff *= -1;\n yDiff *= -1;\n\n lastDiffX = xDiff;\n let lastX = x + xDiff * -PeerProfileAvatars.SCALE;\n if(lastX > 0) lastX = 0;\n else if(lastX < minX) lastX = minX;\n\n this.avatars.style.transform = PeerProfileAvatars.TRANSLATE_TEMPLATE.replace('{x}', lastX + 'px');\n // console.log(xDiff, yDiff);\n return false;\n },\n verifyTouchTarget: (e) => {\n if(!checkScrollTop()) {\n cancelNextClick();\n cancelEvent(e as any as Event);\n return false;\n } else if(this.container.classList.contains('is-single') || freeze) {\n return false;\n }\n\n return true;\n },\n onFirstSwipe: () => {\n const rect = this.avatars.getBoundingClientRect();\n width = rect.width;\n minX = -width * (this.tabs.childElementCount - 1);\n\n /* lastIndex = whichChild(this.tabs.querySelector('.active'));\n x = -width * lastIndex; */\n x = rect.left - this.container.getBoundingClientRect().left;\n\n this.avatars.style.transform = PeerProfileAvatars.TRANSLATE_TEMPLATE.replace('{x}', x + 'px');\n\n this.container.classList.add('is-swiping');\n this.avatars.classList.add('no-transition');\n void this.avatars.offsetLeft; // reflow\n },\n onReset: () => {\n const addIndex = Math.ceil(Math.abs(lastDiffX) / (width / PeerProfileAvatars.SCALE)) * (lastDiffX >= 0 ? 1 : -1);\n cancelNextClick();\n\n // console.log(addIndex);\n\n this.avatars.classList.remove('no-transition');\n fastRaf(() => {\n this.listLoader.go(addIndex);\n this.container.classList.remove('is-swiping');\n });\n }\n });\n\n this.intersectionObserver = new IntersectionObserver((entries) => {\n entries.forEach((entry) => {\n if(!entry.isIntersecting) {\n return;\n }\n\n this.loadNearestToTarget(entry.target);\n });\n });\n\n /* this.listenerSetter.add(rootScope)('avatar_update', (peerId) => {\n if(this.peerId === peerId) {\n const photo = appPeersManager.getPeerPhoto(peerId);\n if(photo) {\n const id = photo.photo_id;\n const previous = this.listLoader.previous;\n for(let i = 0; i < previous.length; ++i) {\n if(previous[i] === id)\n }\n this.listLoader.previous.forEach((_id, idx, arr) => {});\n }\n }\n }); */\n }\n\n public async setPeer(peerId: PeerId) {\n this.peerId = peerId;\n\n const photo = await this.managers.appPeersManager.getPeerPhoto(peerId);\n if(!photo) {\n return;\n }\n\n const listLoader: PeerProfileAvatars['listLoader'] = this.listLoader = new ListLoader({\n loadCount: 50,\n loadMore: (anchor, older, loadCount) => {\n if(!older) return Promise.resolve({count: undefined, items: []});\n\n if(peerId.isUser()) {\n const maxId: Photo.photo['id'] = anchor as any;\n return this.managers.appPhotosManager.getUserPhotos(peerId, maxId, loadCount).then((value) => {\n return {\n count: value.count,\n items: value.photos\n };\n });\n } else {\n const promises: [Promise<ChatFull> | ChatFull, ReturnType<AppMessagesManager['getSearch']>] = [] as any;\n if(!listLoader.current) {\n promises.push(this.managers.appProfileManager.getChatFull(peerId.toChatId()));\n }\n\n promises.push(this.managers.appMessagesManager.getSearch({\n peerId,\n maxId: Number.MAX_SAFE_INTEGER,\n inputFilter: {\n _: 'inputMessagesFilterChatPhotos'\n },\n limit: loadCount,\n backLimit: 0\n }));\n\n return Promise.all(promises).then(async(result) => {\n const value = result.pop() as typeof result[1];\n\n filterChatPhotosMessages(value);\n\n if(!listLoader.current) {\n const chatFull = result[0];\n const message = findAndSplice(value.history, (message) => {\n return ((message as Message.messageService).action as MessageAction.messageActionChannelEditPhoto).photo.id === chatFull.chat_photo.id;\n }) as Message.messageService;\n\n listLoader.current = message || await this.managers.appMessagesManager.generateFakeAvatarMessage(this.peerId, chatFull.chat_photo);\n }\n\n // console.log('avatars loaded:', value);\n return {\n count: value.count,\n items: value.history\n };\n });\n }\n },\n processItem: this.processItem,\n onJump: (item, older) => {\n const id = this.listLoader.index;\n // const nextId = Math.max(0, id);\n const x = 100 * PeerProfileAvatars.SCALE * id;\n this.avatars.style.transform = PeerProfileAvatars.TRANSLATE_TEMPLATE.replace('{x}', `-${x}%`);\n\n const activeTab = this.tabs.querySelector('.active');\n if(activeTab) activeTab.classList.remove('active');\n\n const tab = this.tabs.children[id] as HTMLElement;\n tab.classList.add('active');\n\n this.loadNearestToTarget(this.avatars.children[id]);\n }\n });\n\n if(photo._ === 'userProfilePhoto') {\n listLoader.current = photo.photo_id;\n }\n\n await this.processItem(listLoader.current);\n\n // listLoader.loaded\n listLoader.load(true);\n }\n\n public addTab() {\n const tab = document.createElement('div');\n tab.classList.add(PeerProfileAvatars.BASE_CLASS + '-tab');\n this.tabs.append(tab);\n\n if(this.tabs.childElementCount === 1) {\n tab.classList.add('active');\n }\n\n this.container.classList.toggle('is-single', this.tabs.childElementCount <= 1);\n }\n\n public processItem = async(photoId: Photo.photo['id'] | Message.messageService) => {\n const avatar = document.createElement('div');\n avatar.classList.add(PeerProfileAvatars.BASE_CLASS + '-avatar', 'media-container', 'hide');\n\n this.avatars.append(avatar);\n\n let photo: Photo.photo;\n if(photoId) {\n photo = typeof(photoId) !== 'object' ?\n await this.managers.appPhotosManager.getPhoto(photoId) :\n (photoId.action as MessageAction.messageActionChannelEditPhoto).photo as Photo.photo;\n }\n\n const img = new Image();\n img.classList.add('avatar-photo');\n img.draggable = false;\n\n const loadCallback = async() => {\n if(photo) {\n const res = await wrapPhoto({\n container: avatar,\n photo,\n size: choosePhotoSize(photo, 420, 420, false),\n withoutPreloader: true\n });\n\n [res.images.thumb, res.images.full].filter(Boolean).forEach((img) => {\n img.classList.add('avatar-photo');\n });\n } else {\n const photo = await this.managers.appPeersManager.getPeerPhoto(this.peerId);\n await putAvatar(avatar, this.peerId, photo, 'photo_big', img);\n }\n\n avatar.classList.remove('hide');\n };\n\n if(this.avatars.childElementCount <= LOAD_NEAREST) {\n await loadCallback();\n } else {\n this.intersectionObserver.observe(avatar);\n this.loadCallbacks.set(avatar, loadCallback);\n }\n\n this.addTab();\n\n return photoId;\n };\n\n private loadNearestToTarget(target: Element) {\n const children = Array.from(target.parentElement.children);\n const idx = children.indexOf(target);\n const slice = children.slice(Math.max(0, idx - LOAD_NEAREST), Math.min(children.length, idx + LOAD_NEAREST));\n\n slice.forEach((target) => {\n const callback = this.loadCallbacks.get(target);\n if(callback) {\n callback();\n this.loadCallbacks.delete(target);\n this.intersectionObserver.unobserve(target);\n }\n });\n }\n\n public cleanup() {\n this.listenerSetter.removeAll();\n this.swipeHandler.removeListeners();\n this.intersectionObserver?.disconnect();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_PARALLAX_SUPPORTED from '../environment/parallaxSupport';\nimport deferredPromise from '../helpers/cancellablePromise';\nimport {copyTextToClipboard} from '../helpers/clipboard';\nimport anchorCopy from '../helpers/dom/anchorCopy';\nimport {simulateClickEvent} from '../helpers/dom/clickEvent';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport setInnerHTML from '../helpers/dom/setInnerHTML';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport makeError from '../helpers/makeError';\nimport {makeMediaSize} from '../helpers/mediaSize';\nimport {getMiddleware, MiddlewareHelper} from '../helpers/middleware';\nimport middlewarePromise from '../helpers/middlewarePromise';\nimport {Chat, ChatFull, User, UserFull} from '../layer';\nimport appImManager from '../lib/appManagers/appImManager';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport getServerMessageId from '../lib/appManagers/utils/messageId/getServerMessageId';\nimport getPeerActiveUsernames from '../lib/appManagers/utils/peers/getPeerActiveUsernames';\nimport I18n, {i18n, join} from '../lib/langPack';\nimport wrapRichText from '../lib/richTextProcessor/wrapRichText';\nimport rootScope from '../lib/rootScope';\nimport AvatarElement from './avatar';\nimport CheckboxField from './checkboxField';\nimport {generateDelimiter} from './generateDelimiter';\nimport PeerProfileAvatars from './peerProfileAvatars';\nimport Row from './row';\nimport Scrollable from './scrollable';\nimport SettingSection from './settingSection';\nimport {toast} from './toast';\nimport formatUserPhone from './wrappers/formatUserPhone';\nimport wrapPeerTitle from './wrappers/peerTitle';\nimport wrapTopicNameButton from './wrappers/topicNameButton';\n\nconst setText = (text: Parameters<typeof setInnerHTML>[1], row: Row) => {\n setInnerHTML(row.title, text || undefined);\n row.container.style.display = text ? '' : 'none';\n};\n\nexport default class PeerProfile {\n public element: HTMLElement;\n private avatars: PeerProfileAvatars;\n private avatar: AvatarElement;\n private section: SettingSection;\n private name: HTMLDivElement;\n private subtitle: HTMLDivElement;\n private bio: Row;\n private username: Row;\n private phone: Row;\n private notifications: Row;\n private location: Row;\n private link: Row;\n\n private cleaned: boolean;\n private setMoreDetailsTimeout: number;\n private setPeerStatusInterval: number;\n\n private peerId: PeerId;\n private threadId: number;\n\n private middlewareHelper: MiddlewareHelper;\n\n constructor(\n private managers: AppManagers,\n public scrollable: Scrollable,\n private listenerSetter?: ListenerSetter,\n private isDialog = true\n ) {\n if(!IS_PARALLAX_SUPPORTED) {\n this.scrollable.container.classList.add('no-parallax');\n }\n\n if(!listenerSetter) {\n this.listenerSetter = new ListenerSetter();\n }\n\n this.middlewareHelper = getMiddleware();\n }\n\n public init() {\n this.init = null;\n\n\n this.element = document.createElement('div');\n this.element.classList.add('profile-content');\n\n this.section = new SettingSection({\n noDelimiter: true\n });\n\n this.name = document.createElement('div');\n this.name.classList.add('profile-name');\n\n this.subtitle = document.createElement('div');\n this.subtitle.classList.add('profile-subtitle');\n\n this.bio = new Row({\n title: ' ',\n subtitle: true,\n icon: 'info',\n clickable: (e) => {\n if((e.target as HTMLElement).tagName === 'A') {\n return;\n }\n\n copyTextToClipboard(this.bio.title.textContent);\n toast(I18n.format('BioCopied', true));\n },\n listenerSetter: this.listenerSetter,\n contextMenu: {\n buttons: [{\n icon: 'copy',\n text: 'Text.CopyLabel_About',\n onClick: () => {\n simulateClickEvent(this.bio.container);\n },\n verify: () => !this.peerId.isUser()\n }, {\n icon: 'copy',\n text: 'Text.CopyLabel_Bio',\n onClick: () => {\n simulateClickEvent(this.bio.container);\n },\n verify: () => this.peerId.isUser()\n }]\n }\n });\n\n this.bio.title.classList.add('pre-wrap');\n\n this.username = new Row({\n title: ' ',\n subtitleLangKey: 'Username',\n icon: 'username',\n clickable: () => {\n // const username = await this.managers.appPeersManager.getPeerUsername(this.peerId);\n copyTextToClipboard('@' + this.username.title.textContent);\n toast(I18n.format('UsernameCopied', true));\n },\n listenerSetter: this.listenerSetter,\n contextMenu: {\n buttons: [{\n icon: 'copy',\n text: 'Text.CopyLabel_Username',\n onClick: () => {\n simulateClickEvent(this.username.container);\n }\n }]\n }\n });\n\n this.phone = new Row({\n title: ' ',\n subtitle: true,\n icon: 'phone',\n clickable: () => {\n copyTextToClipboard(this.phone.title.textContent.replace(/\\s/g, ''));\n toast(I18n.format('PhoneCopied', true));\n },\n listenerSetter: this.listenerSetter,\n contextMenu: {\n buttons: [{\n icon: 'copy',\n text: 'Text.CopyLabel_PhoneNumber',\n onClick: () => {\n simulateClickEvent(this.phone.container);\n }\n }, {\n icon: 'info',\n text: 'PeerInfo.Phone.AnonymousInfo',\n textArgs: [(() => {\n const a = document.createElement('a');\n return a;\n })()],\n onClick: () => {\n window.open('https://fragment.com/numbers', '_blank');\n },\n separator: true,\n multiline: true,\n verify: async() => {\n const {isAnonymous} = await this.managers.appUsersManager.getUserPhone(this.peerId.toUserId()) || {};\n return isAnonymous;\n }\n }]\n }\n });\n\n this.link = new Row({\n title: ' ',\n subtitleLangKey: 'SetUrlPlaceholder',\n icon: 'link',\n clickable: () => {\n const url = this.link.title.textContent;\n copyTextToClipboard(url);\n // Promise.resolve(appProfileManager.getChatFull(this.peerId.toChatId())).then((chatFull) => {\n // copyTextToClipboard(chatFull.exported_invite.link);\n const isPrivate = url.includes('/c/');\n toast(I18n.format(isPrivate ? 'LinkCopiedPrivateInfo' : 'LinkCopied', true));\n // });\n },\n listenerSetter: this.listenerSetter,\n contextMenu: {\n buttons: [{\n icon: 'copy',\n text: 'Text.CopyLabel_ShareLink',\n onClick: () => {\n simulateClickEvent(this.link.container);\n }\n }]\n }\n });\n\n this.location = new Row({\n title: ' ',\n subtitleLangKey: 'ChatLocation',\n icon: 'location'\n });\n\n this.section.content.append(\n this.phone.container,\n this.username.container,\n this.location.container,\n this.bio.container,\n this.link.container\n );\n\n const {listenerSetter} = this;\n if(this.isDialog) {\n this.notifications = new Row({\n checkboxField: new CheckboxField({toggle: true}),\n titleLangKey: 'Notifications',\n icon: 'unmute',\n listenerSetter: this.listenerSetter\n });\n\n listenerSetter.add(this.notifications.checkboxField.input)('change', (e) => {\n if(!e.isTrusted) {\n return;\n }\n\n // let checked = this.notificationsCheckbox.checked;\n this.managers.appMessagesManager.togglePeerMute({peerId: this.peerId, threadId: this.threadId});\n });\n\n listenerSetter.add(rootScope)('dialog_notify_settings', async(dialog) => {\n if(this.peerId === dialog.peerId) {\n const muted = await this.managers.appNotificationsManager.isPeerLocalMuted({peerId: this.peerId, respectType: false, threadId: this.threadId});\n this.notifications.checkboxField.checked = !muted;\n }\n });\n\n this.section.content.append(this.notifications.container);\n }\n\n this.element.append(this.section.container);\n\n if(IS_PARALLAX_SUPPORTED) {\n this.element.append(generateDelimiter());\n }\n\n listenerSetter.add(rootScope)('peer_typings', ({peerId}) => {\n if(this.peerId === peerId) {\n this.setPeerStatus();\n }\n });\n\n listenerSetter.add(rootScope)('peer_bio_edit', (peerId) => {\n if(peerId === this.peerId) {\n this.setMoreDetails(true);\n }\n });\n\n const n = async({peerId, threadId}: {peerId: PeerId, threadId?: number}) => {\n if(this.peerId !== peerId) {\n return false;\n }\n\n const isForum = await this.managers.appPeersManager.isForum(this.peerId);\n if(isForum && this.threadId ? this.threadId === threadId : true) {\n return true;\n }\n\n return false;\n };\n\n listenerSetter.add(rootScope)('peer_title_edit', async(data) => {\n if(await n(data)) {\n this.fillUsername();\n this.setMoreDetails(true);\n }\n });\n\n listenerSetter.add(rootScope)('user_update', (userId) => {\n if(this.peerId === userId.toPeerId()) {\n this.setPeerStatus();\n }\n });\n\n listenerSetter.add(rootScope)('contacts_update', async(userId) => {\n if(this.peerId === userId.toPeerId()) {\n const user = await this.managers.appUsersManager.getUser(userId);\n if(!user.pFlags.self || !this.isDialog) {\n this.fillUserPhone();\n }\n }\n });\n\n listenerSetter.add(rootScope)('avatar_update', async(data) => {\n if(await n(data)) {\n this.setAvatar();\n }\n });\n\n this.setPeerStatusInterval = window.setInterval(() => this.setPeerStatus(), 60e3);\n }\n\n private async setPeerStatus<T extends boolean>(\n needClear = false,\n manual?: T\n ): Promise<T extends true ? () => void : void> {\n const peerId = this.peerId;\n\n const callbacks: Array<() => void> = [];\n callbacks.push(() => {\n this.element.classList.toggle('is-me', peerId === rootScope.myId);\n });\n\n let promise: Promise<(() => void) | void> = Promise.resolve();\n if(!(!peerId || (rootScope.myId === peerId && this.isDialog))) {\n const isForum = await this.managers.appPeersManager.isForum(this.peerId);\n const middleware = this.middlewareHelper.get();\n if(isForum && this.threadId) {\n promise = wrapTopicNameButton({\n peerId,\n wrapOptions: {\n middleware\n }\n }).then(({element}) => {\n this.subtitle.replaceChildren(element);\n });\n } else {\n promise = appImManager.setPeerStatus({\n peerId,\n element: this.subtitle,\n needClear,\n useWhitespace: true,\n middleware,\n ignoreSelf: !this.isDialog\n });\n }\n\n promise.then((callback) => callback && callbacks.push(callback));\n }\n\n const callback = () => callbacks.forEach((callback) => callback());\n\n return promise.then(() => {\n if(manual) {\n return callback;\n }\n\n callback();\n }) as any;\n }\n\n public cleanupHTML() {\n [\n this.bio,\n this.phone,\n this.username,\n this.location,\n this.link\n ].forEach((row) => {\n row.container.style.display = 'none';\n });\n\n if(this.notifications) {\n this.notifications.container.style.display = '';\n this.notifications.checkboxField.checked = true;\n }\n\n this.clearSetMoreDetailsTimeout();\n }\n\n private canBeDetailed() {\n return this.peerId !== rootScope.myId || !this.isDialog;\n }\n\n private createAvatar() {\n const avatar = new AvatarElement();\n avatar.classList.add('profile-avatar', 'avatar-120');\n avatar.isDialog = this.isDialog;\n avatar.attachClickEvent();\n return avatar;\n }\n\n private async _setAvatar() {\n const {peerId} = this;\n const isTopic = !!(this.threadId && await this.managers.appPeersManager.isForum(peerId));\n if(this.canBeDetailed() && !isTopic) {\n const photo = await this.managers.appPeersManager.getPeerPhoto(peerId);\n\n if(photo) {\n const oldAvatars = this.avatars;\n this.avatars = new PeerProfileAvatars(this.scrollable, this.managers);\n await this.avatars.setPeer(peerId);\n\n return () => {\n this.avatars.info.append(this.name, this.subtitle);\n\n this.avatar?.remove();\n this.avatar = undefined;\n\n if(oldAvatars) oldAvatars.container.replaceWith(this.avatars.container);\n else this.element.prepend(this.avatars.container);\n\n if(IS_PARALLAX_SUPPORTED) {\n this.scrollable.container.classList.add('parallax');\n }\n };\n }\n }\n\n const avatar = this.createAvatar();\n await avatar.updateWithOptions({\n peerId,\n threadId: isTopic ? this.threadId : undefined,\n wrapOptions: {\n customEmojiSize: makeMediaSize(120, 120),\n middleware: this.middlewareHelper.get()\n }\n });\n\n return () => {\n if(IS_PARALLAX_SUPPORTED) {\n this.scrollable.container.classList.remove('parallax');\n }\n\n if(this.avatars) {\n this.avatars.container.remove();\n this.avatars.cleanup();\n this.avatars = undefined;\n }\n\n this.avatar?.remove();\n this.avatar = avatar;\n\n this.section.content.prepend(this.avatar, this.name, this.subtitle);\n };\n }\n\n private setAvatar<T extends boolean>(manual?: T): T extends true ? Promise<() => void> : Promise<void> {\n const promise = this._setAvatar();\n return manual ? promise : promise.then((callback) => callback()) as any;\n }\n\n private getUsernamesAlso(usernames: string[]) {\n const also = usernames.slice(1);\n if(also.length) {\n const a = also.map((username) => anchorCopy({username}));\n const i = i18n('UsernameAlso', [join(a, false)]);\n return i;\n }\n }\n\n private async fillUsername() {\n const {peerId} = this;\n if(peerId.isUser() && this.canBeDetailed()) {\n const usernames = await this.managers.appPeersManager.getPeerActiveUsernames(peerId);\n const also = this.getUsernamesAlso(usernames);\n\n return () => {\n this.username.subtitle.replaceChildren(also || i18n('Username'));\n setText(usernames[0], this.username);\n };\n }\n }\n\n private async fillUserPhone() {\n const {peerId} = this;\n if(peerId.isUser() && this.canBeDetailed()) {\n const {phone, isAnonymous} = await this.managers.appUsersManager.getUserPhone(peerId.toUserId()) || {};\n\n return () => {\n this.phone.subtitle.replaceChildren(i18n(isAnonymous ? 'AnonymousNumber' : 'Phone'));\n setText(phone ? formatUserPhone(phone) : undefined, this.phone);\n };\n }\n }\n\n private async fillNotifications() {\n const notificationsRow = this.notifications;\n if(!notificationsRow) {\n return;\n }\n\n if(this.canBeDetailed()) {\n const muted = await this.managers.appNotificationsManager.isPeerLocalMuted({peerId: this.peerId, respectType: false, threadId: this.threadId});\n return () => {\n notificationsRow.checkboxField.checked = !muted;\n };\n } else {\n return () => {\n // fastRaf(() => {\n notificationsRow.container.style.display = 'none';\n // });\n };\n }\n }\n\n private async fillName() {\n const {peerId} = this;\n const [element/* , icons */] = await Promise.all([\n wrapPeerTitle({\n peerId,\n dialog: this.isDialog,\n withIcons: !this.threadId,\n threadId: this.threadId\n })\n\n // generateTitleIcons(peerId)\n ]);\n\n return () => {\n replaceContent(this.name, element);\n // this.name.append(...icons);\n };\n }\n\n private async fillRows(manual: Promise<any>) {\n return Promise.all([\n this.fillName(),\n this.fillUsername(),\n this.fillUserPhone(),\n this.fillNotifications(),\n this.setMoreDetails(undefined, manual),\n this.setPeerStatus(true, true)\n ]).then((callbacks) => {\n return () => {\n callbacks.forEach((callback) => callback?.());\n };\n });\n }\n\n public async fillProfileElements() {\n if(!this.cleaned) return;\n this.cleaned = false;\n\n this.cleanupHTML();\n const deferred = deferredPromise<void>();\n const middleware = this.middlewareHelper.get();\n middleware.onClean(() => {\n deferred.reject();\n });\n\n const callbacks = await Promise.all([\n this.setAvatar(true),\n this.fillRows(deferred)\n ]);\n\n return () => {\n deferred.resolve();\n callbacks.forEach((callback) => callback?.());\n };\n }\n\n private async _setMoreDetails(peerId: PeerId, peerFull?: ChatFull | UserFull) {\n const m = this.getMiddlewarePromise();\n const isTopic = !!(this.threadId && await m(this.managers.appPeersManager.isForum(peerId)));\n if(isTopic) {\n let url = 'https://t.me/';\n const threadId = getServerMessageId(this.threadId);\n const username = await m(this.managers.appPeersManager.getPeerUsername(peerId));\n if(username) {\n url += `${username}/${threadId}`;\n } else {\n url += `c/${peerId.toChatId()}/${threadId}`;\n }\n\n return () => {\n setText(url, this.link);\n };\n }\n\n const callbacks: (() => void)[] = [];\n // if(peerFull.about) {\n callbacks.push(() => {\n this.bio.subtitle.replaceChildren(i18n(peerId.isUser() ? 'UserBio' : 'Info'));\n setText(peerFull.about ? wrapRichText(peerFull.about) : undefined, this.bio);\n });\n // }\n\n if(!peerId.isUser()) {\n const chat = await m(this.managers.appChatsManager.getChat(peerId.toChatId())) as Chat.channel;\n const usernames = getPeerActiveUsernames(chat);\n let also: HTMLElement;\n if(usernames.length) {\n also = this.getUsernamesAlso(usernames);\n callbacks.push(() => setText('https://t.me/' + usernames[0], this.link));\n } else {\n const exportedInvite = (peerFull as ChatFull.channelFull).exported_invite;\n if(exportedInvite?._ === 'chatInviteExported') {\n callbacks.push(() => setText(exportedInvite.link, this.link));\n }\n }\n\n callbacks.push(() => this.link.subtitle.replaceChildren(also || i18n('SetUrlPlaceholder')));\n }\n\n const location = (peerFull as ChatFull.channelFull).location;\n if(location?._ == 'channelLocation') {\n callbacks.push(() => setText(location.address, this.location));\n }\n\n this.setMoreDetailsTimeout = window.setTimeout(() => this.setMoreDetails(true), 60e3);\n\n return () => {\n callbacks.forEach((callback) => callback());\n };\n }\n\n private async setMoreDetails(override?: true, manual?: Promise<any>) {\n this.clearSetMoreDetailsTimeout();\n\n const {peerId} = this;\n const m = this.getMiddlewarePromise();\n\n if(!peerId || !this.canBeDetailed() || await m(this.managers.appPeersManager.isPeerRestricted(peerId))) {\n return;\n }\n\n const result = await m(this.managers.acknowledged.appProfileManager.getProfileByPeerId(peerId, override));\n const setPromise = m(result.result).then(async(peerFull) => {\n if(await m(this.managers.appPeersManager.isPeerRestricted(peerId))) {\n // this.log.warn('peer changed');\n return;\n }\n\n return m(this._setMoreDetails(peerId, peerFull));\n });\n\n if(result.cached && manual) {\n return setPromise;\n } else {\n (manual || Promise.resolve())\n .then(() => setPromise)\n .then((callback) => {\n callback?.();\n });\n }\n }\n\n private getMiddlewarePromise() {\n return middlewarePromise(this.middlewareHelper.get(), makeError('MIDDLEWARE'));\n }\n\n public setPeer(peerId: PeerId, threadId?: number) {\n if(this.peerId === peerId && this.threadId === threadId) return;\n\n this.init?.();\n\n this.peerId = peerId;\n this.threadId = threadId;\n\n this.middlewareHelper.clean();\n this.cleaned = true;\n }\n\n public clearSetMoreDetailsTimeout() {\n if(this.setMoreDetailsTimeout !== undefined) {\n clearTimeout(this.setMoreDetailsTimeout);\n this.setMoreDetailsTimeout = undefined;\n }\n }\n\n public destroy() {\n this.peerId = this.threadId = undefined;\n this.clearSetMoreDetailsTimeout();\n clearInterval(this.setPeerStatusInterval);\n this.avatars?.cleanup();\n this.middlewareHelper.destroy();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport mediaSizes from '../helpers/mediaSizes';\nimport {Middleware} from '../helpers/middleware';\nimport {Chat, Document, EmojiStatus, User} from '../layer';\nimport rootScope from '../lib/rootScope';\nimport generateFakeIcon from './generateFakeIcon';\nimport generatePremiumIcon from './generatePremiumIcon';\nimport generateVerifiedIcon from './generateVerifiedIcon';\nimport wrapSticker from './wrappers/sticker';\n\nexport default async function generateTitleIcons(\n peerId: PeerId,\n middleware?: Middleware,\n noVerifiedIcon?: boolean,\n noFakeIcon?: boolean,\n noPremiumIcon?: boolean\n) {\n const elements: HTMLElement[] = [];\n const peer: Chat | User = await rootScope.managers.appPeersManager.getPeer(peerId);\n if((peer as Chat.channel).pFlags.verified && !noVerifiedIcon) {\n elements.push(generateVerifiedIcon());\n }\n\n if(((peer as Chat.channel).pFlags.fake || (peer as User.user).pFlags.scam) && !noFakeIcon) {\n elements.push(generateFakeIcon((peer as User.user).pFlags.scam));\n }\n\n if((peer as User.user).pFlags.premium && !noPremiumIcon) {\n const emojiStatus = (peer as User.user).emoji_status;\n if(emojiStatus && emojiStatus._ !== 'emojiStatusEmpty' && false) {\n const container = document.createElement('span');\n container.classList.add('emoji-status');\n const result = await rootScope.managers.acknowledged.appEmojiManager.getCustomEmojiDocument((emojiStatus as EmojiStatus.emojiStatus).document_id);\n const wrap = async(doc: Document.document) => {\n const size = mediaSizes.active.emojiStatus\n const loadPromises: Promise<any>[] = [];\n await wrapSticker({\n doc,\n div: container,\n width: size.width,\n height: size.height,\n loop: 2,\n play: true,\n group: 'EMOJI-STATUS',\n loadPromises,\n middleware\n // group: 'none'\n });\n\n await Promise.all(loadPromises);\n };\n\n const p = result.result.then(wrap);\n if(result.cached) {\n await p;\n }\n\n elements.push(container);\n } else {\n elements.push(generatePremiumIcon());\n }\n }\n\n return elements;\n}\n","export default function generateVerifiedIcon() {\n const span = document.createElement('span');\n span.classList.add('verified-icon', 'tgico');\n\n const size = 26; // 24\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.setAttributeNS(null, 'viewBox', `0 0 ${size} ${size}`);\n svg.setAttributeNS(null, 'width', `${size}`);\n svg.setAttributeNS(null, 'height', `${size}`);\n svg.classList.add('verified-icon-svg');\n\n const use = document.createElementNS('http://www.w3.org/2000/svg', 'use');\n use.setAttributeNS(null, 'href', '#verified-icon-background');\n use.classList.add('verified-icon-background');\n\n const use2 = document.createElementNS('http://www.w3.org/2000/svg', 'use');\n use2.setAttributeNS(null, 'href', '#verified-icon-check');\n use2.classList.add('verified-icon-check');\n\n // svg.append(use, use2);\n svg.append(use2, use);\n\n span.append(svg);\n\n return span;\n // const span = document.createElement('span');\n // span.classList.add('verified-icon', 'tgico-verified_filled');\n // return span;\n}\n","export default function generatePremiumIcon() {\n const span = document.createElement('span');\n span.classList.add('premium-icon', 'tgico-star');\n return span;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport rootScope from '../lib/rootScope';\nimport {i18n} from '../lib/langPack';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport {NULL_PEER_ID} from '../lib/mtproto/mtproto_config';\nimport limitSymbols from '../helpers/string/limitSymbols';\nimport setInnerHTML, {setDirection} from '../helpers/dom/setInnerHTML';\nimport safeAssign from '../helpers/object/safeAssign';\nimport wrapEmojiText from '../lib/richTextProcessor/wrapEmojiText';\nimport getPeerTitle from './wrappers/getPeerTitle';\nimport generateTitleIcons from './generateTitleIcons';\nimport {wrapTopicIcon} from './wrappers/messageActionTextNewUnsafe';\n\nexport type PeerTitleOptions = {\n peerId?: PeerId,\n fromName?: string,\n plainText?: boolean,\n onlyFirstName?: boolean,\n dialog?: boolean,\n limitSymbols?: number,\n withIcons?: boolean,\n withPremiumIcon?: boolean,\n threadId?: number,\n wrapOptions?: WrapSomethingOptions\n};\n\nconst weakMap: WeakMap<HTMLElement, PeerTitle> = new WeakMap();\n\nrootScope.addEventListener('peer_title_edit', ({peerId, threadId}) => {\n let query = `.peer-title[data-peer-id=\"${peerId}\"]`;\n if(threadId) {\n query += `[data-thread-id=\"${threadId}\"]`;\n }\n\n const elements = Array.from(document.querySelectorAll(query)) as HTMLElement[];\n elements.forEach((element) => {\n const peerTitle = weakMap.get(element);\n peerTitle?.update();\n });\n});\n\nexport default class PeerTitle {\n public element: HTMLElement;\n public options: PeerTitleOptions;\n private hasInner: boolean;\n\n constructor(options?: PeerTitleOptions) {\n this.element = document.createElement('span');\n this.element.classList.add('peer-title');\n setDirection(this.element);\n\n this.options = {};\n\n if(options) {\n this.update(options);\n }\n\n weakMap.set(this.element, this);\n }\n\n public setOptions(options?: PeerTitleOptions) {\n if(!options) {\n return;\n }\n\n safeAssign(this.options, options);\n for(const i in options) {\n // @ts-ignore\n const value = options[i];\n\n if(typeof(value) !== 'object' && typeof(value) !== 'function') {\n // @ts-ignore\n this.element.dataset[i] = value ? '' + (typeof(value) === 'boolean' ? +value : value) : '0';\n }\n }\n }\n\n private setHasInner(hasInner: boolean) {\n if(this.hasInner !== hasInner) {\n this.hasInner = hasInner;\n this.element.classList.toggle('with-icons', hasInner);\n }\n }\n\n public async update(options?: PeerTitleOptions) {\n this.setOptions(options);\n\n let fromName = this.options.fromName;\n if(fromName !== undefined) {\n if(this.options.limitSymbols !== undefined) {\n fromName = limitSymbols(fromName, this.options.limitSymbols, this.options.limitSymbols);\n }\n\n setInnerHTML(this.element, wrapEmojiText(fromName));\n return;\n }\n\n this.options.peerId ??= NULL_PEER_ID;\n\n let hasInner: boolean;\n const {peerId, threadId} = this.options;\n if(peerId !== rootScope.myId || !this.options.dialog) {\n if(threadId) {\n const [topic, isForum] = await Promise.all([\n rootScope.managers.dialogsStorage.getForumTopic(peerId, threadId),\n rootScope.managers.appPeersManager.isForum(peerId)\n ]);\n\n if(!topic && isForum) {\n rootScope.managers.dialogsStorage.getForumTopicById(peerId, threadId).then((forumTopic) => {\n if(!forumTopic && this.options.threadId === threadId) {\n this.options.threadId = undefined;\n this.update({threadId: undefined});\n return;\n }\n\n this.update();\n }, () => {\n if(this.options.threadId === threadId) {\n this.options.threadId = undefined;\n this.update({threadId: undefined});\n }\n });\n\n setInnerHTML(this.element, i18n('Loading'));\n this.setHasInner(false);\n return;\n }\n }\n\n const getTopicIconPromise = threadId && this.options.withIcons ?\n rootScope.managers.dialogsStorage.getForumTopic(peerId, threadId).then((topic) => wrapTopicIcon({...(this.options.wrapOptions ?? {}), topic})) :\n undefined;\n\n const [title, icons, topicIcon] = await Promise.all([\n getPeerTitle(this.options as Required<PeerTitleOptions>),\n (this.options.withIcons && generateTitleIcons(peerId, this.options.wrapOptions?.middleware)) || (this.options.withPremiumIcon && generateTitleIcons(peerId, this.options.wrapOptions?.middleware, true, true)),\n getTopicIconPromise\n ]);\n\n if(icons?.length || topicIcon) {\n const inner = document.createElement('span');\n inner.classList.add('peer-title-inner');\n hasInner = true;\n setInnerHTML(inner, title);\n\n const fragment = document.createDocumentFragment();\n fragment.append(...[topicIcon, inner, ...(icons ?? [])].filter(Boolean));\n setInnerHTML(this.element, fragment);\n } else {\n setInnerHTML(this.element, title);\n }\n } else {\n replaceContent(this.element, i18n(this.options.onlyFirstName ? 'Saved' : 'SavedMessages'));\n }\n\n this.setHasInner(hasInner);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {AppDownloadManager} from '../../lib/appManagers/appDownloadManager';\nimport resizeableImage from '../../lib/cropper';\nimport PopupElement from '.';\nimport {_i18n} from '../../lib/langPack';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport readBlobAsDataURL from '../../helpers/blob/readBlobAsDataURL';\nimport rootScope from '../../lib/rootScope';\nimport appDownloadManager from '../../lib/appManagers/appDownloadManager';\n\nexport default class PopupAvatar extends PopupElement {\n private cropContainer: HTMLElement;\n private input: HTMLInputElement;\n private h6: HTMLElement;\n\n private image = new Image();\n\n private canvas: HTMLCanvasElement;\n private blob: Blob;\n private cropper = {\n crop: () => {},\n removeHandlers: () => {}\n };\n\n private onCrop: (upload: () => ReturnType<AppDownloadManager['upload']>) => void;\n\n constructor(options: Partial<{\n isForum: boolean\n }> = {}) {\n super('popup-avatar', {closable: true, withConfirm: true});\n\n this.h6 = document.createElement('h6');\n _i18n(this.h6, 'Popup.Avatar.Title');\n\n this.btnClose.classList.remove('btn-icon');\n\n this.header.append(this.h6);\n\n this.cropContainer = document.createElement('div');\n this.cropContainer.classList.add('crop');\n this.cropContainer.append(this.image);\n\n if(options.isForum) {\n this.cropContainer.classList.add('is-forum');\n }\n\n this.input = document.createElement('input');\n this.input.type = 'file';\n this.input.style.display = 'none';\n this.listenerSetter.add(this.input)('change', (e: any) => {\n const file = e.target.files[0];\n if(!file) {\n return;\n }\n\n readBlobAsDataURL(file).then((contents) => {\n this.image = new Image();\n this.cropContainer.append(this.image);\n this.image.src = contents;\n\n this.image.onload = () => {\n /* let {w, h} = calcImageInBox(this.image.naturalWidth, this.image.naturalHeight, 460, 554);\n cropContainer.style.width = w + 'px';\n cropContainer.style.height = h + 'px'; */\n this.show();\n\n this.cropper = resizeableImage(this.image, this.canvas);\n this.input.value = '';\n };\n });\n }, false);\n\n this.btnConfirm.className = 'btn-primary btn-color-primary btn-circle btn-crop btn-icon tgico-check z-depth-1';\n attachClickEvent(this.btnConfirm, () => {\n this.cropper.crop();\n this.hide();\n\n this.canvas.toBlob((blob) => {\n this.blob = blob; // save blob to send after reg\n this.darkenCanvas();\n this.resolve();\n }, 'image/jpeg', 1);\n }, {listenerSetter: this.listenerSetter});\n\n this.container.append(this.cropContainer, this.btnConfirm, this.input);\n\n this.addEventListener('closeAfterTimeout', () => {\n this.cropper.removeHandlers();\n if(this.image) {\n this.image.remove();\n }\n });\n }\n\n private resolve() {\n this.onCrop(() => {\n return appDownloadManager.upload(this.blob);\n });\n }\n\n public open(postCanvas: HTMLCanvasElement, onCrop: PopupAvatar['onCrop']) {\n this.canvas = postCanvas;\n this.onCrop = onCrop;\n\n this.input.click();\n }\n\n public darkenCanvas() {\n const ctx = this.canvas.getContext('2d');\n ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';\n ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nfunction resizeableImage(originalImage: HTMLImageElement, canvas?: HTMLCanvasElement) {\n let cropComponent: HTMLDivElement,\n container: HTMLDivElement,\n cropImage: HTMLImageElement,\n event_state: Partial<{\n mouse_x: number,\n mouse_y: number,\n container_width: number,\n container_height: number,\n container_left: number,\n container_top: number\n }> = {},\n keyZoomValue = 4.0,\n MINWIDTH = 50,\n MINHEIGHT = 50,\n CROPWIDTH = 200,\n CROPHEIGHT = 200,\n cropLeft = 0,\n cropTop = 0,\n cropWidth = 0,\n cropHeight = 0,\n scaledRatio = 0;\n\n if(originalImage.complete) init();\n else originalImage.onload = init;\n\n function removeHandlers() {\n container.removeEventListener('mousedown', startMoving);\n container.removeEventListener('touchstart', startMoving);\n container.removeEventListener('wheel', resizing);\n\n document.removeEventListener('mouseup', endMoving);\n document.removeEventListener('touchend', endMoving);\n document.removeEventListener('mousemove', moving);\n document.removeEventListener('touchmove', moving);\n document.removeEventListener('keypress', keyHandler);\n\n cropComponent.remove();\n container.remove();\n cropImage.remove();\n }\n\n function addHandlers() {\n container.addEventListener('mousedown', startMoving, false);\n container.addEventListener('touchstart', startMoving, false);\n container.addEventListener('wheel', resizing, false);\n\n document.addEventListener('keypress', keyHandler, false);\n // document.querySelector('.btn-crop').addEventListener('click', openCropCanvasImg);\n }\n\n function init() {\n originalImage.classList.add('crop-blur');\n originalImage.draggable = false;\n\n cropImage = new Image();\n cropImage.src = originalImage.src;\n cropImage.draggable = false;\n cropImage.classList.add('crop-overlay-image');\n\n if(!canvas) {\n canvas = document.createElement('canvas');\n }\n\n cropComponent = document.createElement('div');\n cropComponent.classList.add('crop-component');\n\n container = document.createElement('div');\n container.classList.add('crop-overlay');\n\n const overlayColor = document.createElement('div');\n overlayColor.classList.add('crop-overlay-color');\n\n cropComponent.appendChild(container);\n const wrapper = originalImage.parentNode as HTMLElement;\n wrapper.appendChild(cropComponent);\n cropComponent.appendChild(cropImage);\n cropComponent.appendChild(originalImage);\n cropComponent.appendChild(overlayColor);\n container.appendChild(cropImage);\n\n cropImage.style.maxWidth = originalImage.width + 'px';\n\n scaledRatio = originalImage.naturalWidth / originalImage.offsetWidth;\n\n const left = originalImage.offsetWidth / 2 - CROPWIDTH / 2;\n const top = originalImage.offsetHeight / 2 - CROPHEIGHT / 2;\n\n updateCropSize(CROPWIDTH, CROPHEIGHT);\n updateCropImage(left, top);\n updateContainer(left, top);\n addHandlers();\n // crop();\n }\n\n function updateCropSize(width: number, height: number) {\n cropWidth = width * scaledRatio;\n cropHeight = height * scaledRatio;\n\n container.style.width = width + 'px';\n container.style.height = height + 'px';\n }\n\n function updateCropImage(left: number, top: number) {\n cropTop = top * scaledRatio;\n cropLeft = left * scaledRatio;\n\n cropImage.style.top = -top + 'px';\n cropImage.style.left = -left + 'px';\n }\n\n function updateContainer(left: number, top: number) {\n container.style.top = top + 'px';\n container.style.left = left + 'px';\n }\n\n // Save the initial event details and container state\n function saveEventState(e: any) {\n event_state.container_width = container.offsetWidth;\n event_state.container_height = container.offsetHeight;\n\n event_state.container_left = container.offsetLeft;\n event_state.container_top = container.offsetTop;\n\n event_state.mouse_x = (e.clientX || e.pageX || e.touches && e.touches[0].clientX) + window.scrollX;\n event_state.mouse_y = (e.clientY || e.pageY || e.touches && e.touches[0].clientY) + window.scrollY;\n }\n\n function imgZoom(zoom: number) {\n zoom = zoom * Math.PI * 2\n let newWidth = Math.floor(container.clientWidth + zoom),\n newHeight = Math.floor(container.clientHeight + zoom),\n w = cropImage.clientWidth,\n h = cropImage.clientHeight,\n left: number,\n top: number,\n right: number,\n bottom: number;\n\n if(newWidth < MINWIDTH) {\n return;\n } else if(newWidth > w) {\n return;\n }\n\n left = container.offsetLeft - (zoom / 2);\n top = container.offsetTop - (zoom / 2);\n right = left + newWidth;\n bottom = top + newHeight;\n\n if(left < 0) left = 0;\n if(top < 0) top = 0;\n\n if(right > w) return;\n if(bottom > h) return;\n\n updateCropSize(newWidth, newWidth);\n updateCropImage(left, top);\n updateContainer(left, top);\n // crop();\n }\n\n function keyHandler(e: KeyboardEvent) {\n e.preventDefault();\n\n switch(String.fromCharCode(e.charCode)) {\n case '+':\n imgZoom(keyZoomValue);\n break;\n case '-':\n imgZoom(-keyZoomValue);\n break;\n }\n }\n\n function resizing(e: any) {\n e.preventDefault();\n imgZoom(e.deltaY > 0 ? 1 : -1);\n }\n\n function startMoving(e: MouseEvent | TouchEvent) {\n e.preventDefault();\n e.stopPropagation();\n\n saveEventState(e);\n\n document.addEventListener('mousemove', moving);\n document.addEventListener('touchmove', moving);\n document.addEventListener('mouseup', endMoving);\n document.addEventListener('touchend', endMoving);\n }\n\n function endMoving(e: MouseEvent | TouchEvent) {\n e.preventDefault();\n\n document.removeEventListener('mouseup', endMoving);\n document.removeEventListener('touchend', endMoving);\n document.removeEventListener('mousemove', moving);\n document.removeEventListener('touchmove', moving);\n }\n\n function moving(e: any) {\n let currentTouch = {x: 0, y: 0},\n left: number,\n top: number,\n w: number,\n h: number;\n\n e.preventDefault();\n e.stopPropagation();\n\n currentTouch.x = e.pageX || e.touches && e.touches[0].pageX;\n currentTouch.y = e.pageY || e.touches && e.touches[0].pageY;\n\n left = currentTouch.x - (event_state.mouse_x - event_state.container_left);\n top = currentTouch.y - (event_state.mouse_y - event_state.container_top);\n w = container.offsetWidth;\n h = container.offsetHeight;\n\n if(left < 0) left = 0;\n else if(left > cropImage.offsetWidth - w) left = cropImage.offsetWidth - w;\n\n if(top < 0) top = 0;\n else if(top > cropImage.offsetHeight - h) top = cropImage.offsetHeight - h;\n\n updateCropImage(left, top);\n updateContainer(left, top);\n // crop();\n }\n\n function crop() {\n canvas.width = cropWidth;\n canvas.height = cropHeight;\n\n const ctx = canvas.getContext('2d');\n ctx.drawImage(originalImage,\n cropLeft, cropTop,\n cropWidth, cropHeight,\n 0, 0,\n cropWidth, cropHeight\n );\n }\n\n return {crop, removeHandlers};\n}\n\nexport default resizeableImage;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement, {PopupOptions} from '.';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport I18n, {FormatterArguments, i18n, LangPackKey} from '../../lib/langPack';\nimport InputField from '../inputField';\n\nexport default class PopupDatePicker extends PopupElement {\n protected controlsDiv: HTMLElement;\n protected monthTitle: HTMLElement;\n protected prevBtn: HTMLElement;\n protected nextBtn: HTMLElement;\n\n protected monthsContainer: HTMLElement;\n protected month: HTMLElement;\n\n protected minMonth: Date;\n protected maxMonth: Date;\n protected minDate: Date;\n protected maxDate: Date;\n protected selectedDate: Date;\n protected selectedMonth: Date;\n protected selectedEl: HTMLElement;\n\n protected timeDiv: HTMLDivElement;\n protected hoursInputField: InputField;\n protected minutesInputField: InputField;\n\n constructor(initDate: Date, public onPick: (timestamp: number) => void, protected options: Partial<{\n noButtons: true,\n noTitle: true,\n minDate: Date,\n maxDate: Date\n withTime: true,\n showOverflowMonths: true\n }> & PopupOptions = {}) {\n super('popup-date-picker', {\n body: true,\n overlayClosable: true,\n buttons: options.noButtons ? [] : [{\n langKey: 'JumpToDate',\n callback: () => {\n if(this.onPick) {\n this.onPick(this.selectedDate.getTime() / 1000 | 0);\n }\n }\n }, {\n langKey: 'Cancel',\n isCancel: true\n }],\n title: true,\n ...options\n });\n\n this.minDate = options.minDate || new Date('2013-08-01T00:00:00');\n\n if(initDate < this.minDate) {\n initDate.setFullYear(this.minDate.getFullYear(), this.minDate.getMonth(), this.minDate.getDate());\n }\n\n // Controls\n this.controlsDiv = document.createElement('div');\n this.controlsDiv.classList.add('date-picker-controls');\n\n this.prevBtn = document.createElement('button');\n this.prevBtn.classList.add('btn-icon', 'tgico-down', 'date-picker-prev');\n attachClickEvent(this.prevBtn, this.onPrevClick, {listenerSetter: this.listenerSetter});\n\n this.nextBtn = document.createElement('button');\n this.nextBtn.classList.add('btn-icon', 'tgico-down', 'date-picker-next');\n attachClickEvent(this.nextBtn, this.onNextClick, {listenerSetter: this.listenerSetter});\n\n this.monthTitle = document.createElement('div');\n this.monthTitle.classList.add('date-picker-month-title');\n\n this.controlsDiv.append(this.prevBtn, this.monthTitle, this.nextBtn);\n\n // Month\n this.monthsContainer = document.createElement('div');\n this.monthsContainer.classList.add('date-picker-months');\n attachClickEvent(this.monthsContainer, this.onDateClick, {listenerSetter: this.listenerSetter});\n\n this.body.append(this.controlsDiv, this.monthsContainer);\n\n // Time inputs\n if(options.withTime) {\n this.timeDiv = document.createElement('div');\n this.timeDiv.classList.add('date-picker-time');\n\n const delimiter = document.createElement('div');\n delimiter.classList.add('date-picker-time-delimiter');\n delimiter.append(':');\n\n const handleTimeInput = (max: number, inputField: InputField, onInput: (length: number) => void, onOverflow?: (number: number) => void) => {\n const maxString = '' + max;\n this.listenerSetter.add(inputField.input)('input', (e) => {\n let value = inputField.value.replace(/\\D/g, '');\n if(value.length > 2) {\n value = value.slice(0, 2);\n } else {\n if((value.length === 1 && +value[0] > +maxString[0]) || (value.length === 2 && +value > max)) {\n if(value.length === 2 && onOverflow) {\n onOverflow(+value[1]);\n }\n\n value = '0' + value[0];\n }\n }\n\n inputField.setValueSilently(value);\n onInput(value.length);\n });\n };\n\n this.hoursInputField = new InputField({plainText: true});\n this.minutesInputField = new InputField({plainText: true});\n\n handleTimeInput(23, this.hoursInputField, (length) => {\n if(length === 2) {\n this.minutesInputField.input.focus();\n }\n\n this.setTimeTitle();\n }, (number) => {\n this.minutesInputField.value = (number + this.minutesInputField.value).slice(0, 2);\n });\n handleTimeInput(59, this.minutesInputField, (length) => {\n if(!length) {\n this.hoursInputField.input.focus();\n }\n\n this.setTimeTitle();\n });\n\n this.selectedDate = initDate;\n\n initDate.setMinutes(initDate.getMinutes() + 10);\n\n this.hoursInputField.setValueSilently(('0' + initDate.getHours()).slice(-2));\n this.minutesInputField.setValueSilently(('0' + initDate.getMinutes()).slice(-2));\n\n initDate.setHours(0, 0, 0, 0);\n\n this.timeDiv.append(this.hoursInputField.container, delimiter, this.minutesInputField.container);\n\n attachClickEvent(this.btnConfirm, () => {\n if(this.onPick) {\n this.selectedDate.setHours(+this.hoursInputField.value || 0, +this.minutesInputField.value || 0, 0, 0);\n this.onPick(this.selectedDate.getTime() / 1000 | 0);\n }\n\n this.hide();\n }, {listenerSetter: this.listenerSetter});\n\n this.body.append(this.timeDiv);\n\n this.prevBtn.classList.add('primary');\n this.nextBtn.classList.add('primary');\n }\n\n const popupCenterer = document.createElement('div');\n popupCenterer.classList.add('popup-centerer');\n popupCenterer.append(this.container);\n this.element.append(popupCenterer);\n\n // const passed = (initDate.getTime() - (initDate.getTimezoneOffset() * 60000)) % 86400000;\n // this.selectedDate = this.maxDate = new Date(initDate.getTime() - passed);\n initDate.setHours(0, 0, 0, 0);\n this.selectedDate = initDate;\n\n this.maxDate = options.maxDate || new Date();\n this.maxDate.setHours(0, 0, 0, 0);\n\n this.selectedMonth = new Date(this.selectedDate);\n this.selectedMonth.setDate(1);\n\n this.maxMonth = new Date(this.maxDate);\n this.maxMonth.setDate(1);\n\n this.minMonth = new Date(this.minDate);\n this.minMonth.setHours(0, 0, 0, 0);\n this.minMonth.setDate(1);\n\n if(this.selectedMonth.getTime() === this.minMonth.getTime()) {\n this.prevBtn.setAttribute('disabled', 'true');\n }\n\n if(this.selectedMonth.getTime() === this.maxMonth.getTime()) {\n this.nextBtn.setAttribute('disabled', 'true');\n }\n\n if(options.noTitle) {\n this.setTitle = () => {};\n }\n\n this.setTimeTitle();\n this.setTitle();\n this.setMonth();\n }\n\n onPrevClick = (e: MouseEvent) => {\n this.selectedMonth.setMonth(this.selectedMonth.getMonth() - 1);\n this.setMonth();\n\n if(this.selectedMonth.getTime() === this.minMonth.getTime()) {\n this.prevBtn.setAttribute('disabled', 'true');\n }\n\n this.nextBtn.removeAttribute('disabled');\n };\n\n onNextClick = (e: MouseEvent) => {\n this.selectedMonth.setMonth(this.selectedMonth.getMonth() + 1);\n this.setMonth();\n\n if(this.selectedMonth.getTime() === this.maxMonth.getTime()) {\n this.nextBtn.setAttribute('disabled', 'true');\n }\n\n this.prevBtn.removeAttribute('disabled');\n };\n\n onDateClick = (e: MouseEvent) => {\n // cancelEvent(e);\n const target = e.target as HTMLElement;\n\n if(!target.dataset.timestamp) return;\n\n if(this.selectedEl) {\n if(this.selectedEl === target) return;\n this.selectedEl.classList.remove('active');\n }\n\n this.selectedEl = target;\n\n target.classList.add('active');\n const timestamp = +target.dataset.timestamp;\n\n this.selectedDate = new Date(timestamp);\n\n this.setTitle();\n this.setTimeTitle();\n };\n\n public setTimeTitle() {\n if(this.btnConfirm && this.selectedDate) {\n let key: LangPackKey;\n const args: FormatterArguments = [];\n const date = new Date();\n date.setHours(0, 0, 0, 0);\n\n const timeOptions: Intl.DateTimeFormatOptions = {\n minute: '2-digit',\n hour: '2-digit'\n };\n\n const sendDate = new Date(this.selectedDate.getTime());\n sendDate.setHours(+this.hoursInputField.value, +this.minutesInputField.value);\n\n if(this.selectedDate.getTime() === date.getTime()) {\n key = 'Schedule.SendToday';\n }/* else if(this.selectedDate.getTime() === (date.getTime() + 86400e3)) {\n dayStr = 'Tomorrow';\n } */ else {\n key = 'Schedule.SendDate';\n\n const dateOptions: Intl.DateTimeFormatOptions = {\n month: 'short',\n day: 'numeric'\n };\n\n if(sendDate.getFullYear() !== date.getFullYear()) {\n dateOptions.year = 'numeric';\n }\n\n args.push(new I18n.IntlDateElement({\n date: sendDate,\n options: dateOptions\n }).element);\n }\n\n args.push(new I18n.IntlDateElement({\n date: sendDate,\n options: timeOptions\n }).element);\n\n this.btnConfirm.firstChild.replaceWith(i18n(key, args));\n }\n }\n\n public setTitle() {\n // const splitted = this.selectedDate.toString().split(' ', 3);\n // this.title.innerText = splitted[0] + ', ' + splitted[1] + ' ' + splitted[2];\n this.title.textContent = '';\n this.title.append(new I18n.IntlDateElement({\n date: this.selectedDate,\n options: {\n day: 'numeric',\n month: 'long',\n weekday: 'short'\n }\n }).element);\n }\n\n private renderElement(disabled: boolean, innerText: string | HTMLElement = '') {\n const el = document.createElement('button');\n el.classList.add('btn-icon', 'date-picker-month-date');\n\n if(disabled) {\n el.setAttribute('disabled', 'true');\n }\n\n if(innerText) {\n el.append(innerText);\n }\n\n return el;\n }\n\n public setMonth() {\n const firstDate = new Date(this.selectedMonth);\n\n const options: Intl.DateTimeFormatOptions = {\n year: 'numeric',\n month: this.timeDiv && mediaSizes.isMobile ? 'short' : 'long'\n };\n\n this.monthTitle.textContent = '';\n this.monthTitle.append(new I18n.IntlDateElement({date: firstDate, options}).element);\n // this.monthTitle.innerText = (this.timeDiv && mediaSizes.isMobile ? monthName.slice(0, 3) : monthName) + ' ' + this.selectedMonth.getFullYear();\n\n if(this.month) {\n this.month.remove();\n }\n\n this.month = document.createElement('div');\n this.month.classList.add('date-picker-month');\n\n const weekStartDate = new Date();\n const day = weekStartDate.getDay();\n if(day !== 1) {\n weekStartDate.setHours(-24 * (day - 1));\n }\n\n for(let i = 0; i < 7; ++i) {\n const el = this.renderElement(true, new I18n.IntlDateElement({date: weekStartDate, options: {weekday: 'narrow'}}).element);\n el.classList.remove('date-picker-month-date');\n el.classList.add('date-picker-month-day');\n this.month.append(el);\n weekStartDate.setDate(weekStartDate.getDate() + 1);\n }\n\n // 0 - sunday\n let dayIndex = firstDate.getDay() - 1;\n if(dayIndex === -1) dayIndex = 7 - 1;\n\n const clonedDate = new Date(firstDate.getTime());\n clonedDate.setDate(clonedDate.getDate() - dayIndex - 1);\n\n // Padding first week\n for(let i = 0; i < dayIndex; ++i) {\n if(this.options.showOverflowMonths) {\n clonedDate.setDate(clonedDate.getDate() + 1);\n this.month.append(this.renderElement(true, '' + clonedDate.getDate()));\n } else {\n this.month.append(this.renderElement(true));\n }\n }\n\n do {\n const date = firstDate.getDate();\n const el = this.renderElement(firstDate > this.maxDate || firstDate < this.minDate, '' + date);\n el.dataset.timestamp = '' + firstDate.getTime();\n\n if(firstDate.getTime() === this.selectedDate.getTime()) {\n this.selectedEl = el;\n el.classList.add('active');\n }\n\n this.month.append(el);\n\n firstDate.setDate(date + 1);\n } while(firstDate.getDate() !== 1);\n\n const remainder = this.month.childElementCount % 7;\n if(this.options.showOverflowMonths && remainder) {\n for(let i = remainder; i < 7; ++i) {\n this.month.append(this.renderElement(true, '' + firstDate.getDate()));\n firstDate.setDate(firstDate.getDate() + 1);\n }\n }\n\n const lines = Math.ceil(this.month.childElementCount / 7);\n this.container.dataset.lines = '' + lines;\n\n this.monthsContainer.append(this.month);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '.';\nimport type {PeerType} from '../../lib/appManagers/appPeersManager';\nimport {FormatterArguments, LangPackKey} from '../../lib/langPack';\nimport wrapPeerTitle from '../wrappers/peerTitle';\nimport PopupPeer, {PopupPeerButtonCallbackCheckboxes, PopupPeerOptions} from './peer';\n\nexport default class PopupDeleteDialog {\n constructor(\n private peerId: PeerId,\n // actionType: 'leave' | 'delete',\n private peerType?: PeerType,\n private onSelect?: (promise: Promise<any>) => void,\n private threadId?: number\n ) {\n this.construct();\n }\n\n private async construct() {\n let {peerId, peerType, onSelect, threadId} = this;\n const peerTitleElement = await wrapPeerTitle({peerId, threadId: threadId});\n\n const managers = PopupElement.MANAGERS;\n if(peerType === undefined) {\n peerType = await managers.appPeersManager.getDialogType(peerId);\n }\n\n /* const callbackFlush = (checked: PopupPeerButtonCallbackCheckboxes) => {\n const promise = appMessagesManager.flushHistory(peerId, checkboxes ? !checked[checkboxes[0].text] : undefined);\n onSelect && onSelect(promise);\n }; */\n\n const callbackLeave = (checked: PopupPeerButtonCallbackCheckboxes, flush = checkboxes && !!checked.size) => {\n let promise = managers.appChatsManager.leave(peerId.toChatId());\n\n if(flush) {\n promise = promise.then(() => {\n return managers.appMessagesManager.flushHistory(peerId);\n }) as any;\n }\n\n onSelect?.(promise);\n };\n\n const callbackDelete = (checked: PopupPeerButtonCallbackCheckboxes) => {\n let promise: Promise<any>;\n\n if(threadId) {\n promise = managers.appMessagesManager.flushHistory(peerId, false, true, threadId);\n } else if(peerId.isUser()) {\n promise = managers.appMessagesManager.flushHistory(peerId, false, checkboxes ? !!checked.size : undefined);\n } else {\n if(checked.size) {\n promise = managers.appChatsManager.delete(peerId.toChatId());\n } else {\n return callbackLeave(checked);\n }\n }\n\n onSelect?.(promise);\n };\n\n let title: LangPackKey,\n titleArgs: FormatterArguments,\n description: LangPackKey,\n descriptionArgs: FormatterArguments,\n buttons: PopupPeerOptions['buttons'],\n checkboxes: PopupPeerOptions['checkboxes'];\n switch(peerType) {\n case 'channel': {\n if(/* actionType === 'delete' && */await managers.appChatsManager.hasRights(peerId.toChatId(), 'delete_chat')) {\n title = 'ChannelDeleteMenu';\n description = 'AreYouSureDeleteAndExitChannel';\n buttons = [{\n langKey: 'ChannelDeleteMenu',\n isDanger: true,\n callback: callbackDelete\n }];\n\n checkboxes = [{\n text: 'DeleteChannelForAll'\n }];\n } else {\n title = 'LeaveChannelMenu';\n description = 'ChannelLeaveAlertWithName';\n descriptionArgs = [peerTitleElement];\n buttons = [{\n langKey: 'LeaveChannel',\n isDanger: true,\n callback: callbackLeave\n }];\n }\n\n break;\n }\n\n /* case 'megagroup': {\n title = 'Leave Group?';\n description = `Are you sure you want to leave this group?`;\n buttons = [{\n text: 'LEAVE ' + peerTitleElement,\n isDanger: true,\n callback: callbackLeave\n }];\n\n break;\n } */\n\n case 'chat': {\n title = 'DeleteChatUser';\n description = 'AreYouSureDeleteThisChatWithUser';\n descriptionArgs = [peerTitleElement];\n\n buttons = [{\n langKey: 'DeleteChatUser',\n isDanger: true,\n callback: callbackDelete\n }];\n\n checkboxes = [{\n text: 'DeleteMessagesOptionAlso',\n textArgs: [\n await wrapPeerTitle({peerId})\n ]\n }];\n\n break;\n }\n\n case 'saved': {\n title = 'DeleteChatUser';\n description = 'AreYouSureDeleteThisChatSavedMessages';\n buttons = [{\n langKey: 'DeleteChatUser',\n isDanger: true,\n callback: callbackDelete\n }];\n\n break;\n }\n\n case 'megagroup':\n case 'group': {\n if(threadId) {\n title = 'DeleteTopics';\n titleArgs = [1];\n description = 'DeleteSelectedTopic';\n descriptionArgs = [peerTitleElement];\n buttons = [{\n langKey: 'Delete',\n isDanger: true,\n callback: callbackDelete\n }];\n } else if(/* actionType === 'delete' && */await managers.appChatsManager.hasRights(peerId.toChatId(), 'delete_chat')) {\n title = 'DeleteMegaMenu';\n description = 'AreYouSureDeleteAndExit';\n buttons = [{\n langKey: 'DeleteMegaMenu',\n isDanger: true,\n callback: callbackDelete\n }];\n\n checkboxes = [{\n text: 'DeleteChat.DeleteGroupForAll'\n }];\n } else {\n title = 'LeaveMegaMenu';\n description = 'AreYouSureDeleteAndExitName';\n descriptionArgs = [peerTitleElement];\n buttons = [{\n langKey: 'DeleteChatUser',\n isDanger: true,\n callback: (checkboxes) => callbackLeave(checkboxes, true)\n }];\n }\n\n break;\n }\n }\n\n PopupElement.createPopup(PopupPeer, 'popup-delete-chat', {\n peerId,\n threadId,\n titleLangKey: title,\n titleLangArgs: titleArgs,\n descriptionLangKey: description,\n descriptionLangArgs: descriptionArgs,\n buttons,\n checkboxes\n }).show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport rootScope from '../../lib/rootScope';\nimport PopupElement, {addCancelButton} from '.';\nimport PopupPeer, {PopupPeerButtonCallbackCheckboxes, PopupPeerOptions} from './peer';\nimport {ChatType} from '../chat/chat';\nimport {i18n, LangPackKey} from '../../lib/langPack';\nimport hasRights from '../../lib/appManagers/utils/chats/hasRights';\nimport filterAsync from '../../helpers/array/filterAsync';\nimport wrapPeerTitle from '../wrappers/peerTitle';\n\nexport default class PopupDeleteMessages {\n constructor(\n private peerId: PeerId,\n private mids: number[],\n private type: ChatType,\n private onConfirm?: () => void,\n private threadId?: number\n ) {\n this.construct();\n }\n\n private async construct() {\n let {peerId, mids, type, onConfirm, threadId} = this;\n\n const peerTitleElement = await wrapPeerTitle({peerId, threadId});\n\n const managers = PopupElement.MANAGERS;\n\n mids = mids.slice();\n const callback = (checked: PopupPeerButtonCallbackCheckboxes, revoke?: boolean) => {\n onConfirm && onConfirm();\n if(type === 'scheduled') {\n managers.appMessagesManager.deleteScheduledMessages(peerId, mids);\n } else {\n managers.appMessagesManager.deleteMessages(peerId, mids, !!checked.size || revoke);\n }\n };\n\n const buttons: PopupPeerOptions['buttons'] = [{\n langKey: 'Delete',\n isDanger: true,\n callback\n }];\n const checkboxes: PopupPeerOptions['checkboxes'] = [];\n let title: LangPackKey, titleArgs: any[], description: LangPackKey, descriptionArgs: any[];\n if(mids.length === 1) {\n title = 'DeleteSingleMessagesTitle';\n } else {\n title = 'DeleteMessagesTitle';\n titleArgs = [i18n('messages', [mids.length])];\n }\n\n if(await managers.appPeersManager.isMegagroup(peerId)) {\n description = mids.length === 1 ? 'AreYouSureDeleteSingleMessageMega' : 'AreYouSureDeleteFewMessagesMega';\n } else {\n description = mids.length === 1 ? 'AreYouSureDeleteSingleMessage' : 'AreYouSureDeleteFewMessages';\n }\n\n if(peerId === rootScope.myId || type === 'scheduled') {\n\n } else {\n if(peerId.isUser()) {\n checkboxes.push({\n text: 'DeleteMessagesOptionAlso',\n textArgs: [peerTitleElement]\n });\n } else {\n const chat = await managers.appChatsManager.getChat(peerId.toChatId());\n\n const _hasRights = hasRights(chat, 'delete_messages');\n if(chat._ === 'chat') {\n const canRevoke = _hasRights ? mids.slice() : await filterAsync(mids, async(mid) => {\n const message = await managers.appMessagesManager.getMessageByPeer(peerId, mid);\n return message.fromId === rootScope.myId;\n });\n\n if(canRevoke.length) {\n if(canRevoke.length === mids.length) {\n checkboxes.push({\n text: 'DeleteForAll'\n });\n } else {\n checkboxes.push({\n text: 'DeleteMessagesOption'\n });\n\n description = 'DeleteMessagesTextGroup';\n descriptionArgs = [i18n('messages', [canRevoke.length])];\n // description = `You can also delete the ${canRevoke.length} message${canRevoke.length > 1 ? 's' : ''} you sent from the inboxes of other group members by pressing \"${buttonText}\".`;\n }\n }\n } else {\n buttons[0].callback = (checked) => callback(checked, true);\n }\n }\n }\n\n addCancelButton(buttons);\n\n const popup = PopupElement.createPopup(PopupPeer, 'popup-delete-chat', {\n peerId,\n threadId,\n titleLangKey: title,\n titleLangArgs: titleArgs,\n descriptionLangKey: description,\n descriptionLangArgs: descriptionArgs,\n buttons,\n checkboxes\n });\n\n popup.show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {ChatRights} from '../../lib/appManagers/appChatsManager';\nimport flatten from '../../helpers/array/flatten';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport rootScope from '../../lib/rootScope';\nimport {toastNew} from '../toast';\nimport PopupPickUser from './pickUser';\nimport getMediaFromMessage from '../../lib/appManagers/utils/messages/getMediaFromMessage';\nimport PopupElement from '.';\n\nexport default class PopupForward extends PopupPickUser {\n constructor(\n peerIdMids?: {[fromPeerId: PeerId]: number[]},\n onSelect?: (peerId: PeerId) => Promise<void> | void,\n chatRightsAction: ChatRights[] = ['send_plain']\n ) {\n super({\n peerTypes: ['dialogs', 'contacts'],\n onSelect: !peerIdMids && onSelect ? onSelect : async(peerId) => {\n if(onSelect) {\n const res = onSelect(peerId);\n if(res instanceof Promise) {\n await res;\n }\n }\n\n if(peerId === rootScope.myId) {\n let count = 0;\n for(const fromPeerId in peerIdMids) {\n const mids = peerIdMids[fromPeerId];\n count += mids.length;\n this.managers.appMessagesManager.forwardMessages(peerId, fromPeerId.toPeerId(), mids);\n }\n\n toastNew({\n langPackKey: count > 0 ? 'FwdMessagesToSavedMessages' : 'FwdMessageToSavedMessages'\n });\n\n return;\n }\n\n appImManager.setInnerPeer({peerId});\n appImManager.chat.input.initMessagesForward(peerIdMids);\n },\n placeholder: 'ShareModal.Search.ForwardPlaceholder',\n chatRightsActions: chatRightsAction,\n selfPresence: 'ChatYourSelf'\n });\n }\n\n public static async create(...args: ConstructorParameters<typeof PopupForward>) {\n const [peerIdMids] = args;\n const messagesPromises = Object.keys(peerIdMids).map((peerId) => {\n const mids = peerIdMids[peerId as any as number];\n return mids.map((mid) => {\n return rootScope.managers.appMessagesManager.getMessageByPeer(peerId.toPeerId(), mid);\n });\n });\n\n const messages = await Promise.all(flatten(messagesPromises));\n const actions: Set<ChatRights> = new Set();\n messages.forEach((message) => {\n if(!message) {\n return;\n }\n\n const media = getMediaFromMessage(message);\n let action: ChatRights;\n if(!media) {\n if(message.viaBotId) {\n action = 'send_inline';\n } else {\n action = 'send_plain';\n }\n } else {\n if(media._ === 'webPage') {\n action = 'embed_links';\n } else if(media._ === 'photo') {\n action = 'send_photos';\n } else if(media._ === 'game') {\n action = 'send_games';\n } else {\n switch(media.type) {\n case 'audio':\n action = 'send_audios';\n break;\n case 'gif':\n action = 'send_gifs';\n break;\n case 'round':\n action = 'send_roundvideos';\n break;\n case 'sticker':\n action = 'send_stickers';\n break;\n case 'voice':\n action = 'send_voices';\n break;\n case 'video':\n action = 'send_videos';\n break;\n default:\n action = 'send_docs';\n break;\n }\n }\n }\n\n if(action) {\n actions.add(action);\n }\n });\n\n PopupElement.createPopup(PopupForward, args[0], args[1], Array.from(actions));\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport ripple from '../ripple';\nimport animationIntersector from '../animationIntersector';\nimport appNavigationController, {NavigationItem} from '../appNavigationController';\nimport {i18n, LangPackKey, _i18n} from '../../lib/langPack';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport blurActiveElement from '../../helpers/dom/blurActiveElement';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport {attachClickEvent, simulateClickEvent} from '../../helpers/dom/clickEvent';\nimport isSendShortcutPressed from '../../helpers/dom/isSendShortcutPressed';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport EventListenerBase, {EventListenerListeners} from '../../helpers/eventListenerBase';\nimport {addFullScreenListener, getFullScreenElement} from '../../helpers/dom/fullScreen';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport overlayCounter from '../../helpers/overlayCounter';\nimport Scrollable from '../scrollable';\nimport {getMiddleware, MiddlewareHelper} from '../../helpers/middleware';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\n\nexport type PopupButton = {\n text?: string,\n callback?: () => void,\n langKey?: LangPackKey,\n langArgs?: any[],\n isDanger?: boolean,\n isCancel?: boolean,\n element?: HTMLButtonElement,\n noRipple?: boolean\n};\n\nexport type PopupOptions = Partial<{\n closable: boolean,\n overlayClosable: boolean,\n withConfirm: LangPackKey | boolean,\n body: boolean,\n confirmShortcutIsSendShortcut: boolean,\n withoutOverlay: boolean,\n scrollable: boolean,\n buttons: Array<PopupButton>,\n title: boolean | LangPackKey,\n titleRaw: string\n}>;\n\nexport interface PopupElementConstructable<T extends PopupElement = any> {\n new(...args: any[]): T;\n}\n\nconst DEFAULT_APPEND_TO = document.body;\nlet appendPopupTo = DEFAULT_APPEND_TO;\n\nconst onFullScreenChange = () => {\n appendPopupTo = getFullScreenElement() || DEFAULT_APPEND_TO;\n PopupElement.reAppend();\n};\n\naddFullScreenListener(DEFAULT_APPEND_TO, onFullScreenChange);\n\ntype PopupListeners = {\n close: () => void,\n closeAfterTimeout: () => void\n};\n\nexport default class PopupElement<T extends EventListenerListeners = {}> extends EventListenerBase<PopupListeners & T> {\n private static POPUPS: PopupElement<any>[] = [];\n public static MANAGERS: AppManagers;\n\n protected element = document.createElement('div');\n protected container = document.createElement('div');\n protected header = document.createElement('div');\n protected title = document.createElement('div');\n protected btnClose: HTMLElement;\n protected btnConfirm: HTMLButtonElement;\n protected body: HTMLElement;\n protected buttonsEl: HTMLElement;\n\n protected onEscape: () => boolean = () => true;\n\n protected navigationItem: NavigationItem;\n\n protected listenerSetter: ListenerSetter;\n\n protected confirmShortcutIsSendShortcut: boolean;\n protected btnConfirmOnEnter: HTMLElement;\n\n protected withoutOverlay: boolean;\n\n protected managers: AppManagers;\n\n protected scrollable: Scrollable;\n\n protected buttons: Array<PopupButton>;\n\n protected middlewareHelper: MiddlewareHelper;\n\n constructor(className: string, options: PopupOptions = {}) {\n super(false);\n this.element.classList.add('popup');\n this.element.className = 'popup' + (className ? ' ' + className : '');\n this.container.classList.add('popup-container', 'z-depth-1');\n\n this.header.classList.add('popup-header');\n\n if(options.title || options.titleRaw) {\n this.title.classList.add('popup-title');\n if(typeof(options.title) === 'string') {\n _i18n(this.title, options.title);\n } else if(options.titleRaw) {\n this.title.append(wrapEmojiText(options.titleRaw));\n }\n\n this.header.append(this.title);\n }\n\n this.middlewareHelper = getMiddleware();\n this.listenerSetter = new ListenerSetter();\n this.managers = PopupElement.MANAGERS;\n\n this.confirmShortcutIsSendShortcut = options.confirmShortcutIsSendShortcut;\n\n if(options.closable) {\n this.btnClose = document.createElement('span');\n this.btnClose.classList.add('btn-icon', 'popup-close', 'tgico-close');\n // ripple(this.closeBtn);\n this.header.prepend(this.btnClose);\n\n attachClickEvent(this.btnClose, this.hide, {listenerSetter: this.listenerSetter, once: true});\n }\n\n this.withoutOverlay = options.withoutOverlay;\n if(this.withoutOverlay) {\n this.element.classList.add('no-overlay');\n }\n\n if(options.overlayClosable) {\n attachClickEvent(this.element, (e: MouseEvent) => {\n if(!findUpClassName(e.target, 'popup-container')) {\n this.hide();\n }\n }, {listenerSetter: this.listenerSetter});\n }\n\n if(options.withConfirm) {\n this.btnConfirm = document.createElement('button');\n this.btnConfirm.classList.add('btn-primary', 'btn-color-primary');\n if(options.withConfirm !== true) {\n this.btnConfirm.append(i18n(options.withConfirm));\n }\n this.header.append(this.btnConfirm);\n ripple(this.btnConfirm);\n }\n\n this.container.append(this.header);\n if(options.body) {\n this.body = document.createElement('div');\n this.body.classList.add('popup-body');\n this.container.append(this.body);\n }\n\n if(options.scrollable) {\n const scrollable = this.scrollable = new Scrollable(this.body);\n this.attachScrollableListeners();\n\n if(!this.body) {\n this.container.insertBefore(scrollable.container, this.header.nextSibling);\n }\n }\n\n let btnConfirmOnEnter = this.btnConfirm;\n const buttons = this.buttons = options.buttons;\n if(buttons?.length) {\n const buttonsDiv = this.buttonsEl = document.createElement('div');\n buttonsDiv.classList.add('popup-buttons');\n\n const buttonsElements = buttons.map((b) => {\n const button = document.createElement('button');\n button.className = 'btn' + (b.isDanger ? ' danger' : ' primary');\n\n if(!b.noRipple) {\n ripple(button);\n }\n\n if(b.text) {\n button.textContent = b.text;\n } else {\n button.append(i18n(b.langKey, b.langArgs));\n }\n\n attachClickEvent(button, () => {\n b.callback?.();\n this.destroy();\n }, {listenerSetter: this.listenerSetter, once: true});\n\n return b.element = button;\n });\n\n if(!btnConfirmOnEnter && buttons.length === 2) {\n const button = buttons.find((button) => !button.isCancel);\n if(button) {\n btnConfirmOnEnter = button.element;\n }\n }\n\n buttonsDiv.append(...buttonsElements);\n this.container.append(buttonsDiv);\n }\n\n this.btnConfirmOnEnter = btnConfirmOnEnter;\n\n this.element.append(this.container);\n\n PopupElement.POPUPS.push(this);\n }\n\n protected attachScrollableListeners(setClassOn?: HTMLElement) {\n return this.scrollable.attachBorderListeners(setClassOn);\n }\n\n protected onContentUpdate() {\n if(this.scrollable) {\n this.scrollable.onAdditionalScroll();\n }\n }\n\n public show() {\n this.navigationItem = {\n type: 'popup',\n onPop: () => this.destroy(),\n onEscape: this.onEscape\n };\n\n appNavigationController.pushItem(this.navigationItem);\n\n blurActiveElement(); // * hide mobile keyboard\n appendPopupTo.append(this.element);\n void this.element.offsetWidth; // reflow\n this.element.classList.add('active');\n\n this.onContentUpdate();\n\n if(!this.withoutOverlay) {\n overlayCounter.isOverlayActive = true;\n animationIntersector.checkAnimations2(true);\n }\n\n // cannot add event instantly because keydown propagation will fire it\n // if(this.btnConfirmOnEnter) {\n setTimeout(() => {\n if(!this.element.classList.contains('active')) {\n return;\n }\n\n this.listenerSetter.add(document.body)('keydown', (e) => {\n if(PopupElement.POPUPS[PopupElement.POPUPS.length - 1] !== this) {\n return;\n }\n\n if(this.confirmShortcutIsSendShortcut ? isSendShortcutPressed(e) : e.key === 'Enter') {\n simulateClickEvent(this.btnConfirmOnEnter);\n cancelEvent(e);\n }\n });\n }, 0);\n // }\n }\n\n public hide = () => {\n appNavigationController.backByItem(this.navigationItem);\n };\n\n protected destroy() {\n this.dispatchEvent<PopupListeners>('close');\n this.element.classList.add('hiding');\n this.element.classList.remove('active');\n this.listenerSetter.removeAll();\n this.middlewareHelper.destroy();\n\n if(!this.withoutOverlay) {\n overlayCounter.isOverlayActive = false;\n }\n\n appNavigationController.removeItem(this.navigationItem);\n this.navigationItem = undefined;\n\n indexOfAndSplice(PopupElement.POPUPS, this);\n\n // ! calm\n onFullScreenChange();\n\n setTimeout(() => {\n this.element.remove();\n this.dispatchEvent<PopupListeners>('closeAfterTimeout');\n this.cleanup();\n this.scrollable?.destroy();\n\n if(!this.withoutOverlay) {\n animationIntersector.checkAnimations2(false);\n }\n }, 150);\n }\n\n public static reAppend() {\n this.POPUPS.forEach((popup) => {\n const {element, container} = popup;\n const parentElement = element.parentElement;\n if(parentElement && parentElement !== appendPopupTo && appendPopupTo !== container) {\n appendPopupTo.append(element);\n }\n });\n }\n\n public static getPopups<T extends PopupElement>(popupConstructor: PopupElementConstructable<T>) {\n return this.POPUPS.filter((element) => element instanceof popupConstructor) as T[];\n }\n\n public static createPopup<T extends /* PopupElement */any, A extends Array<any>>(ctor: {new(...args: A): T}, ...args: A) {\n const popup = new ctor(...args);\n return popup;\n }\n}\n\nexport const addCancelButton = (buttons: PopupButton[]) => {\n const button = buttons.find((b) => b.isCancel);\n if(!button) {\n buttons.push({\n langKey: 'Cancel',\n isCancel: true\n });\n }\n\n return buttons;\n};\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement, {addCancelButton} from '.';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport numberThousandSplitter from '../../helpers/number/numberThousandSplitter';\nimport {ChatInvite} from '../../layer';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport {i18n, _i18n} from '../../lib/langPack';\nimport {NULL_PEER_ID} from '../../lib/mtproto/mtproto_config';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport AvatarElement from '../avatar';\nimport putPhoto from '../putPhoto';\nimport {toastNew} from '../toast';\nimport wrapPhoto from '../wrappers/photo';\n\n// const FAKE_CHAT_ID = Number.MAX_SAFE_INTEGER - 0x1000;\n\nexport default class PopupJoinChatInvite extends PopupElement {\n constructor(\n private hash: string,\n private chatInvite: ChatInvite.chatInvite\n ) {\n super('popup-join-chat-invite', {\n closable: true,\n overlayClosable: true,\n body: true,\n buttons: addCancelButton([{\n langKey: chatInvite.pFlags.request_needed ? 'RequestJoin.Button' : (chatInvite.pFlags.broadcast ? 'JoinByPeekChannelTitle' : 'JoinByPeekGroupTitle'),\n callback: () => {\n this.managers.appChatsManager.importChatInvite(hash)\n .then((chatId) => {\n const peerId = chatId.toPeerId(true);\n appImManager.setInnerPeer({peerId});\n }, (error) => {\n if(error.type === 'INVITE_REQUEST_SENT') {\n toastNew({langPackKey: 'RequestToJoinSent'});\n }\n });\n }\n }])\n });\n\n this.construct();\n }\n\n private async construct() {\n this.header.remove();\n /* const fakeChat: Chat.channel | Chat.chat = {\n _: chatInvite.pFlags.channel ? 'channel' : 'chat',\n id: FAKE_CHAT_ID,\n title: chatInvite.title,\n photo: chatInvite.photo as any,\n date: Date.now() / 1000 | 0,\n version: 0,\n participants_count: chatInvite.participants_count,\n pFlags: chatInvite.pFlags as any\n };\n\n appChatsManager.saveApiChat(fakeChat); */\n\n const {chatInvite, managers, hash} = this;\n\n const avatarElem = new AvatarElement();\n avatarElem.classList.add('avatar-100');\n avatarElem.isDialog = false;\n if(chatInvite.photo._ === 'photo') {\n chatInvite.photo = await managers.appPhotosManager.savePhoto(chatInvite.photo);\n wrapPhoto({\n container: avatarElem,\n message: null,\n photo: chatInvite.photo,\n boxHeight: 100,\n boxWidth: 100,\n withoutPreloader: true\n });\n avatarElem.style.width = avatarElem.style.height = '';\n } else {\n putPhoto({\n div: avatarElem,\n peerId: NULL_PEER_ID,\n isDialog: false,\n title: chatInvite.title\n });\n }\n\n const title = document.createElement('div');\n title.classList.add('chat-title');\n setInnerHTML(title, wrapEmojiText(chatInvite.title));\n // avatarElem.setAttribute('peer', '' + -fakeChat.id);\n\n const isBroadcast = chatInvite.pFlags.broadcast;\n const peopleCount = i18n(isBroadcast ? 'Subscribers' : 'Members', [numberThousandSplitter(chatInvite.participants_count)]);\n peopleCount.classList.add('chat-participants-count');\n\n this.body.append(avatarElem, title, peopleCount);\n\n if(chatInvite.pFlags.request_needed) {\n const caption = document.createElement('div');\n _i18n(caption, isBroadcast ? 'RequestToJoinChannelDescription' : 'RequestToJoinGroupDescription');\n caption.classList.add('chat-participants-count', 'request-caption');\n\n this.body.append(caption);\n }\n\n this.show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport liteMode from '../../helpers/liteMode';\nimport {doubleRaf} from '../../helpers/schedulers';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport {LangPackKey, _i18n, i18n} from '../../lib/langPack';\nimport {ApiLimitType} from '../../lib/mtproto/api_methods';\nimport rootScope from '../../lib/rootScope';\nimport PopupPeer from './peer';\n\nconst a: {[type in ApiLimitType]?: {\n title: LangPackKey,\n description: LangPackKey,\n descriptionPremium: LangPackKey,\n descriptionLocked: LangPackKey,\n icon: string\n}} = {\n pin: {\n title: 'LimitReached',\n description: 'LimitReachedPinDialogs',\n descriptionPremium: 'LimitReachedPinDialogsPremium',\n descriptionLocked: 'LimitReachedPinDialogsLocked',\n icon: 'limit_pin'\n },\n folders: {\n title: 'LimitReached',\n description: 'LimitReachedFolders',\n descriptionPremium: 'LimitReachedFoldersPremium',\n descriptionLocked: 'LimitReachedFoldersLocked',\n icon: 'limit_folders'\n }\n};\n\nclass P extends PopupPeer {\n constructor(options: {\n isPremium: boolean,\n limit: number,\n limitPremium: number\n }, _a: typeof a[keyof typeof a]) {\n super('popup-limit', {\n buttons: options.isPremium === undefined ? [{\n langKey: 'LimitReached.Ok',\n isCancel: true\n }] : (options.isPremium ? [{\n langKey: 'OK',\n isCancel: true\n }] : [{\n langKey: 'IncreaseLimit',\n callback: () => {\n appImManager.openPremiumBot();\n },\n noRipple: true\n }, {\n langKey: 'Cancel',\n isCancel: true\n }]),\n descriptionLangKey: options.isPremium === undefined ? _a.descriptionLocked : (options.isPremium ? _a.descriptionPremium : _a.description),\n descriptionLangArgs: options.isPremium ? [options.limitPremium] : [options.limit, options.limitPremium],\n titleLangKey: _a.title\n });\n\n const isLocked = options.isPremium === undefined;\n if(isLocked) {\n this.element.classList.add('is-locked');\n } else if(options.isPremium) {\n this.element.classList.add('is-premium');\n } else {\n const button = this.buttons.find((b) => !b.isCancel);\n button.element.classList.add('popup-limit-button');\n const i = document.createElement('i');\n i.classList.add('popup-limit-button-icon', 'tgico-premium_double');\n button.element.append(i);\n }\n\n const limitContainer = document.createElement('div');\n limitContainer.classList.add('popup-limit-line');\n\n const hint = document.createElement('div');\n hint.classList.add('popup-limit-hint');\n const i = document.createElement('span');\n i.classList.add('popup-limit-hint-icon', 'tgico-' + _a.icon);\n hint.append(i, '' + (options.isPremium ? options.limitPremium : options.limit));\n\n limitContainer.append(hint);\n\n if(!isLocked) {\n const limit = document.createElement('div');\n limit.classList.add('limit-line');\n\n const free = document.createElement('div');\n free.classList.add('limit-line-free');\n\n const premium = document.createElement('div');\n premium.classList.add('limit-line-premium');\n\n limit.append(free, premium);\n\n _i18n(free, 'LimitFree');\n premium.append(i18n('LimitPremium'), '' + options.limitPremium);\n\n limitContainer.append(limit);\n }\n\n this.container.insertBefore(limitContainer, this.description);\n\n // if(options.isPremium === false) {\n // this.buttons.pop().element.remove();\n // }\n\n const setHintActive = () => {\n hint.classList.add('active');\n };\n\n if(liteMode.isAvailable('animations')) {\n doubleRaf().then(setHintActive);\n } else {\n setHintActive();\n }\n }\n}\n\nexport default async function showLimitPopup(type: keyof typeof a) {\n const _a = a[type];\n const [appConfig, limit, limitPremium] = await Promise.all([\n rootScope.managers.apiManager.getAppConfig(),\n ...[false, true].map((v) => rootScope.managers.apiManager.getLimit(type, v))\n ]);\n const isLocked = appConfig.premium_purchase_blocked;\n new P({\n isPremium: isLocked ? undefined : rootScope.premium,\n limit,\n limitPremium\n }, _a).show();\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport tsNow from '../../helpers/tsNow';\nimport {LangPackKey} from '../../lib/langPack';\nimport {MUTE_UNTIL} from '../../lib/mtproto/mtproto_config';\nimport {RadioFormFromValues} from '../row';\nimport PopupPeer from './peer';\n\nconst ONE_HOUR = 3600;\nconst times: {value: number | string, langPackKey: LangPackKey, checked?: boolean}[] = [{\n value: ONE_HOUR,\n langPackKey: 'ChatList.Mute.1Hour'\n}, {\n value: ONE_HOUR * 4,\n langPackKey: 'ChatList.Mute.4Hours'\n}, {\n value: ONE_HOUR * 8,\n langPackKey: 'ChatList.Mute.8Hours'\n}, {\n value: ONE_HOUR * 24,\n langPackKey: 'ChatList.Mute.1Day'\n}, {\n value: ONE_HOUR * 24 * 3,\n langPackKey: 'ChatList.Mute.3Days'\n}, {\n value: -1,\n langPackKey: 'ChatList.Mute.Forever',\n checked: true\n}];\n\nexport default class PopupMute extends PopupPeer {\n constructor(peerId: PeerId, threadId?: number) {\n super('popup-mute', {\n peerId,\n titleLangKey: 'Notifications',\n buttons: [{\n langKey: 'ChatList.Context.Mute',\n callback: () => {\n this.managers.appMessagesManager.mutePeer({peerId, muteUntil: time === -1 ? MUTE_UNTIL : tsNow(true) + time, threadId});\n }\n }],\n body: true\n });\n\n let time: number;\n const radioForm = RadioFormFromValues(times, (value) => {\n time = +value;\n });\n\n this.body.append(radioForm);\n\n this.show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport pause from './schedulers/pause';\nimport {makeMediaSize} from './mediaSize';\nimport scaleMediaElement from './canvas/scaleMediaElement';\nimport preloadVideo from './preloadVideo';\n\nexport function createPosterFromMedia(media: HTMLVideoElement | HTMLImageElement) {\n let width: number, height: number;\n if(media instanceof HTMLVideoElement) {\n width = media.videoWidth;\n height = media.videoHeight;\n } else {\n width = media.naturalWidth;\n height = media.naturalHeight;\n }\n\n return scaleMediaElement({\n media,\n mediaSize: makeMediaSize(width, height),\n boxSize: makeMediaSize(320, 240),\n quality: .9\n });\n}\n\nexport function createPosterFromVideo(video: HTMLVideoElement): ReturnType<typeof createPosterFromMedia> {\n return new Promise((resolve, reject) => {\n video.onseeked = () => {\n video.onseeked = () => {\n createPosterFromMedia(video).then(resolve);\n\n video.onseeked = undefined;\n };\n\n video.currentTime = 0;\n };\n\n video.onerror = reject;\n video.currentTime = Math.min(video.duration, 1);\n });\n}\n\nexport async function createPosterForVideo(url: string) {\n const video = await preloadVideo(url);\n\n return Promise.race([\n pause(2000) as Promise<undefined>,\n createPosterFromVideo(video)\n ]);\n}\n\n\n","/**\n * @returns duration in ms\n */\nexport default function getGifDuration(image: HTMLImageElement) {\n const src = image.src;\n\n return fetch(src)\n .then((response) => response.arrayBuffer())\n .then((arrayBuffer) => {\n const d = new Uint8Array(arrayBuffer);\n // Thanks to http://justinsomnia.org/2006/10/gif-animation-duration-calculation/\n // And http://www.w3.org/Graphics/GIF/spec-gif89a.txt\n let duration = 0;\n for(let i = 0, length = d.length; i < length; ++i) {\n // Find a Graphic Control Extension hex(21F904__ ____ __00)\n if(d[i] == 0x21 &&\n d[i + 1] == 0xF9 &&\n d[i + 2] == 0x04 &&\n d[i + 7] == 0x00) {\n // Swap 5th and 6th bytes to get the delay per frame\n const delay = (d[i + 5] << 8) | (d[i + 4] & 0xFF);\n\n // Should be aware browsers have a minimum frame delay\n // e.g. 6ms for IE, 2ms modern browsers (50fps)\n duration += delay < 2 ? 10 : delay;\n }\n }\n\n return duration / 1000;\n });\n}\n","export type AUDIO_MIME_TYPE = 'audio/mpeg' | 'audio/aac' | 'audio/wav';\nconst AUDIO_MIME_TYPES_SUPPORTED: Set<AUDIO_MIME_TYPE> = new Set([\n 'audio/mpeg',\n 'audio/aac',\n 'audio/wav'\n]);\n\nexport default AUDIO_MIME_TYPES_SUPPORTED;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type Chat from '../chat/chat';\nimport type {SendFileDetails} from '../../lib/appManagers/appMessagesManager';\nimport type {ChatRights} from '../../lib/appManagers/appChatsManager';\nimport PopupElement from '.';\nimport Scrollable from '../scrollable';\nimport {toast, toastNew} from '../toast';\nimport SendContextMenu from '../chat/sendContextMenu';\nimport {createPosterFromMedia, createPosterFromVideo} from '../../helpers/createPoster';\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport I18n, {FormatterArguments, i18n, LangPackKey} from '../../lib/langPack';\nimport calcImageInBox from '../../helpers/calcImageInBox';\nimport placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport MEDIA_MIME_TYPES_SUPPORTED from '../../environment/mediaMimeTypesSupport';\nimport getGifDuration from '../../helpers/getGifDuration';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport createVideo from '../../helpers/dom/createVideo';\nimport prepareAlbum from '../prepareAlbum';\nimport {makeMediaSize, MediaSize} from '../../helpers/mediaSize';\nimport {ThumbCache} from '../../lib/storages/thumbs';\nimport onMediaLoad from '../../helpers/onMediaLoad';\nimport apiManagerProxy from '../../lib/mtproto/mtprotoworker';\nimport {THUMB_TYPE_FULL} from '../../lib/mtproto/mtproto_config';\nimport wrapDocument from '../wrappers/document';\nimport createContextMenu from '../../helpers/dom/createContextMenu';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport wrapMediaSpoiler, {toggleMediaSpoiler} from '../wrappers/mediaSpoiler';\nimport {MiddlewareHelper} from '../../helpers/middleware';\nimport {AnimationItemGroup} from '../animationIntersector';\nimport scaleMediaElement from '../../helpers/canvas/scaleMediaElement';\nimport {doubleRaf} from '../../helpers/schedulers';\nimport defineNotNumerableProperties from '../../helpers/object/defineNotNumerableProperties';\nimport {DocumentAttribute, Photo, PhotoSize} from '../../layer';\nimport {getPreviewBytesFromURL} from '../../helpers/bytes/getPreviewURLFromBytes';\nimport {renderImageFromUrlPromise} from '../../helpers/dom/renderImageFromUrl';\nimport ButtonMenuToggle from '../buttonMenuToggle';\nimport partition from '../../helpers/array/partition';\nimport InputFieldAnimated from '../inputFieldAnimated';\nimport IMAGE_MIME_TYPES_SUPPORTED from '../../environment/imageMimeTypesSupport';\nimport VIDEO_MIME_TYPES_SUPPORTED from '../../environment/videoMimeTypesSupport';\nimport rootScope from '../../lib/rootScope';\nimport shake from '../../helpers/dom/shake';\nimport AUDIO_MIME_TYPES_SUPPORTED from '../../environment/audioMimeTypeSupport';\nimport liteMode from '../../helpers/liteMode';\n\ntype SendFileParams = SendFileDetails & {\n file?: File,\n scaledBlob?: Blob,\n noSound?: boolean,\n itemDiv: HTMLElement,\n mediaSpoiler?: HTMLElement,\n middlewareHelper: MiddlewareHelper\n // strippedBytes?: PhotoSize.photoStrippedSize['bytes']\n};\n\nlet currentPopup: PopupNewMedia;\n\nconst MAX_WIDTH = 400 - 16;\n\nexport function getCurrentNewMediaPopup() {\n return currentPopup;\n}\n\nexport default class PopupNewMedia extends PopupElement {\n private mediaContainer: HTMLElement;\n private wasInputValue: string;\n\n private willAttach: Partial<{\n type: 'media' | 'document',\n isMedia: true,\n group: boolean,\n sendFileDetails: SendFileParams[]\n }>;\n private messageInputField: InputFieldAnimated;\n private captionLengthMax: number;\n\n private animationGroup: AnimationItemGroup;\n private _scrollable: Scrollable;\n private inputContainer: HTMLDivElement;\n\n constructor(\n private chat: Chat,\n private files: File[],\n willAttachType: PopupNewMedia['willAttach']['type'],\n private ignoreInputValue?: boolean\n ) {\n super('popup-send-photo popup-new-media', {\n closable: true,\n withConfirm: 'Modal.Send',\n confirmShortcutIsSendShortcut: true,\n body: true,\n title: true,\n scrollable: true\n });\n\n this.animationGroup = '';\n this.construct(willAttachType);\n }\n\n public static async canSend(peerId: PeerId, onlyVisible?: boolean) {\n const actions: ChatRights[] = [\n 'send_photos',\n 'send_videos',\n 'send_docs',\n 'send_audios',\n 'send_gifs'\n ];\n\n const actionsPromises = actions.map((action) => {\n return peerId.isAnyChat() && !onlyVisible ? rootScope.managers.appChatsManager.hasRights(peerId.toChatId(), action) : true;\n });\n\n const out: {[action in ChatRights]?: boolean} = {};\n\n const results = await Promise.all(actionsPromises);\n actions.forEach((action, idx) => {\n out[action] = results[idx];\n })\n\n return out;\n }\n\n private async construct(willAttachType: PopupNewMedia['willAttach']['type']) {\n this.willAttach = {\n type: willAttachType,\n sendFileDetails: [],\n group: true\n };\n\n const captionMaxLength = await this.managers.apiManager.getLimit('caption');\n this.captionLengthMax = captionMaxLength;\n\n const canSend = await PopupNewMedia.canSend(this.chat.peerId, true);\n\n const canSendPhotos = canSend.send_photos;\n const canSendVideos = canSend.send_videos;\n const canSendDocs = canSend.send_docs;\n\n attachClickEvent(this.btnConfirm, () => this.send(), {listenerSetter: this.listenerSetter});\n\n const btnMenu = await ButtonMenuToggle({\n listenerSetter: this.listenerSetter,\n direction: 'bottom-left',\n buttons: [{\n icon: 'image',\n text: 'Popup.Attach.AsMedia',\n onClick: () => this.changeType('media'),\n verify: () => {\n if(!this.hasAnyMedia() || this.willAttach.type !== 'document') {\n return false;\n }\n\n if(!canSendPhotos && !canSendVideos) {\n return false;\n }\n\n if(!canSendPhotos || !canSendVideos) {\n const mimeTypes = canSendPhotos ? IMAGE_MIME_TYPES_SUPPORTED : VIDEO_MIME_TYPES_SUPPORTED;\n const {media, files} = this.partition(mimeTypes);\n if(files.length) {\n return false;\n }\n }\n\n return true;\n }\n }, {\n icon: 'document',\n text: 'SendAsFile',\n onClick: () => this.changeType('document'),\n verify: () => this.files.length === 1 && this.willAttach.type !== 'document' && canSendDocs\n }, {\n icon: 'document',\n text: 'SendAsFiles',\n onClick: () => this.changeType('document'),\n verify: () => this.files.length > 1 && this.willAttach.type !== 'document' && canSendDocs\n }, {\n icon: 'groupmedia',\n text: 'Popup.Attach.GroupMedia',\n onClick: () => this.changeGroup(true),\n verify: () => !this.willAttach.group && this.canGroupSomething()\n }, {\n icon: 'groupmediaoff',\n text: 'Popup.Attach.UngroupMedia',\n onClick: () => this.changeGroup(false),\n verify: () => this.willAttach.group && this.canGroupSomething()\n }, {\n icon: 'mediaspoiler',\n text: 'EnablePhotoSpoiler',\n onClick: () => this.changeSpoilers(true),\n verify: () => this.canToggleSpoilers(true, true)\n }, {\n icon: 'mediaspoiler',\n text: 'Popup.Attach.EnableSpoilers',\n onClick: () => this.changeSpoilers(true),\n verify: () => this.canToggleSpoilers(true, false)\n }, {\n icon: 'mediaspoileroff',\n text: 'DisablePhotoSpoiler',\n onClick: () => this.changeSpoilers(false),\n verify: () => this.canToggleSpoilers(false, true)\n }, {\n icon: 'mediaspoileroff',\n text: 'Popup.Attach.RemoveSpoilers',\n onClick: () => this.changeSpoilers(false),\n verify: () => this.canToggleSpoilers(false, false)\n }]\n });\n\n this.header.append(btnMenu);\n\n this.btnConfirm.remove();\n\n this.mediaContainer = document.createElement('div');\n this.mediaContainer.classList.add('popup-photo');\n this.scrollable.container.append(this.mediaContainer);\n\n const inputContainer = this.inputContainer = document.createElement('div');\n inputContainer.classList.add('popup-input-container');\n\n const c = document.createElement('div');\n c.classList.add('popup-input-inputs', 'input-message-container');\n\n this.messageInputField = new InputFieldAnimated({\n placeholder: 'PreviewSender.CaptionPlaceholder',\n name: 'message',\n withLinebreaks: true,\n maxLength: this.captionLengthMax\n });\n\n this.listenerSetter.add(this.scrollable.container)('scroll', this.onScroll);\n this.listenerSetter.add(this.messageInputField.input)('scroll', this.onScroll);\n\n this.messageInputField.input.classList.replace('input-field-input', 'input-message-input');\n this.messageInputField.inputFake.classList.replace('input-field-input', 'input-message-input');\n\n c.append(this.messageInputField.input, this.messageInputField.inputFake);\n inputContainer.append(c, this.btnConfirm);\n\n if(!this.ignoreInputValue) {\n this.messageInputField.value = this.wasInputValue = this.chat.input.messageInputField.input.innerHTML;\n this.chat.input.messageInputField.value = '';\n }\n\n this.container.append(inputContainer);\n\n this.attachFiles();\n\n this.addEventListener('close', () => {\n this.files.length = 0;\n this.willAttach.sendFileDetails.length = 0;\n\n if(currentPopup === this) {\n currentPopup = undefined;\n }\n });\n\n let target: HTMLElement, isMedia: boolean, item: SendFileParams;\n createContextMenu({\n buttons: [{\n icon: 'mediaspoiler',\n text: 'EnablePhotoSpoiler',\n onClick: () => {\n this.applyMediaSpoiler(item);\n },\n verify: () => isMedia && !item.mediaSpoiler\n }, {\n icon: 'mediaspoileroff',\n text: 'DisablePhotoSpoiler',\n onClick: () => {\n this.removeMediaSpoiler(item);\n },\n verify: () => !!(isMedia && item.mediaSpoiler)\n }],\n listenTo: this.mediaContainer,\n listenerSetter: this.listenerSetter,\n findElement: (e) => {\n target = findUpClassName(e.target, 'popup-item');\n isMedia = target.classList.contains('popup-item-media');\n item = this.willAttach.sendFileDetails.find((i) => i.itemDiv === target);\n return target;\n }\n });\n\n if(this.chat.type !== 'scheduled') {\n const sendMenu = new SendContextMenu({\n onSilentClick: () => {\n this.chat.input.sendSilent = true;\n this.send();\n },\n onScheduleClick: () => {\n this.chat.input.scheduleSending(() => {\n this.send();\n });\n },\n openSide: 'top-left',\n onContextElement: this.btnConfirm,\n listenerSetter: this.listenerSetter\n });\n\n sendMenu.setPeerId(this.chat.peerId);\n\n this.container.append(sendMenu.sendMenu);\n }\n\n currentPopup = this;\n }\n\n private onScroll = () => {\n const {input} = this.messageInputField;\n this.scrollable.onAdditionalScroll();\n if(input.scrollTop > 0 && input.scrollHeight > 130) {\n this.scrollable.container.classList.remove('scrolled-bottom');\n }\n };\n\n private async applyMediaSpoiler(item: SendFileParams, noAnimation?: boolean) {\n const middleware = item.middlewareHelper.get();\n const {width: widthStr, height: heightStr} = item.itemDiv.style;\n\n let width: number, height: number;\n if(item.itemDiv.classList.contains('album-item')) {\n const {width: containerWidthStr, height: containerHeightStr} = item.itemDiv.parentElement.style;\n const containerWidth = parseInt(containerWidthStr);\n const containerHeight = parseInt(containerHeightStr);\n\n width = +widthStr.slice(0, -1) / 100 * containerWidth;\n height = +heightStr.slice(0, -1) / 100 * containerHeight;\n } else {\n width = parseInt(widthStr);\n height = parseInt(heightStr);\n }\n\n const {url} = await scaleMediaElement({\n media: item.itemDiv.firstElementChild as HTMLImageElement,\n boxSize: makeMediaSize(40, 40),\n mediaSize: makeMediaSize(width, height),\n toDataURL: true,\n quality: 0.2\n });\n\n const strippedBytes = getPreviewBytesFromURL(url);\n const photoSize: PhotoSize.photoStrippedSize = {\n _: 'photoStrippedSize',\n bytes: strippedBytes,\n type: 'i'\n };\n\n item.strippedBytes = strippedBytes;\n\n const photo: Photo.photo = {\n _: 'photo',\n sizes: [\n photoSize\n ],\n id: 0,\n access_hash: 0,\n date: 0,\n dc_id: 0,\n file_reference: [],\n pFlags: {}\n };\n\n const mediaSpoiler = await wrapMediaSpoiler({\n middleware,\n width,\n height,\n animationGroup: this.animationGroup,\n media: photo\n });\n\n if(!middleware()) {\n return;\n }\n\n if(!noAnimation) {\n mediaSpoiler.classList.add('is-revealing');\n }\n\n item.mediaSpoiler = mediaSpoiler;\n item.itemDiv.append(mediaSpoiler);\n\n await doubleRaf();\n if(!middleware()) {\n return;\n }\n\n toggleMediaSpoiler({\n mediaSpoiler,\n reveal: false\n });\n }\n\n private removeMediaSpoiler(item: SendFileParams) {\n toggleMediaSpoiler({\n mediaSpoiler: item.mediaSpoiler,\n reveal: true,\n destroyAfter: true\n });\n\n item.mediaSpoiler = undefined;\n }\n\n public appendDrops(element: HTMLElement) {\n this.body.append(element);\n }\n\n get type() {\n return this.willAttach.type;\n }\n\n set type(type: PopupNewMedia['willAttach']['type']) {\n this.willAttach.type = type;\n }\n\n private partition(mimeTypes = MEDIA_MIME_TYPES_SUPPORTED) {\n const [media, files] = partition(this.willAttach.sendFileDetails, (d) => mimeTypes.has(d.file.type));\n return {\n media,\n files\n };\n }\n\n private mediaCount() {\n return this.partition().media.length;\n }\n\n private hasAnyMedia() {\n return this.mediaCount() > 0;\n }\n\n private canGroupSomething() {\n const {media, files} = this.partition();\n return media.length > 1 || files.length > 1;\n }\n\n private canToggleSpoilers(toggle: boolean, single: boolean) {\n let good = this.willAttach.type === 'media' && this.hasAnyMedia();\n if(single && good) {\n good = this.files.length === 1;\n }\n\n if(good) {\n const media = this.willAttach.sendFileDetails\n .filter((d) => MEDIA_MIME_TYPES_SUPPORTED.has(d.file.type))\n const mediaWithSpoilers = media.filter((d) => d.mediaSpoiler);\n\n good = single ? true : media.length > 1;\n\n if(good) {\n good = toggle ? media.length !== mediaWithSpoilers.length : media.length === mediaWithSpoilers.length;\n }\n }\n\n return good;\n }\n\n private changeType(type: PopupNewMedia['willAttach']['type']) {\n this.willAttach.type = type;\n this.attachFiles();\n }\n\n public changeGroup(group: boolean) {\n this.willAttach.group = group;\n this.attachFiles();\n }\n\n public changeSpoilers(toggle: boolean) {\n this.partition().media.forEach((item) => {\n if(toggle && !item.mediaSpoiler) {\n this.applyMediaSpoiler(item);\n } else if(!toggle && item.mediaSpoiler) {\n this.removeMediaSpoiler(item);\n }\n });\n }\n\n public addFiles(files: File[]) {\n const toPush = files.filter((file) => {\n const found = this.files.find((_file) => {\n return _file.lastModified === file.lastModified && _file.name === file.name && _file.size === file.size;\n });\n\n return !found;\n });\n\n if(toPush.length) {\n this.files.push(...toPush);\n this.attachFiles();\n }\n }\n\n private onKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement;\n const {input} = this.messageInputField;\n if(target !== input) {\n if(target.tagName === 'INPUT' || target.isContentEditable) {\n return;\n }\n\n input.focus();\n placeCaretAtEnd(input);\n }\n };\n\n private async send(force = false) {\n let caption = this.messageInputField.value;\n if(caption.length > this.captionLengthMax) {\n toast(I18n.format('Error.PreviewSender.CaptionTooLong', true));\n return;\n }\n\n const {peerId, input} = this.chat;\n\n const canSend = await PopupNewMedia.canSend(peerId);\n const willAttach = this.willAttach;\n willAttach.isMedia = willAttach.type === 'media' || undefined;\n const {sendFileDetails, isMedia} = willAttach;\n\n let foundBad = false;\n this.iterate((sendFileParams) => {\n if(foundBad) {\n return;\n }\n\n const isBad: (LangPackKey | boolean)[] = sendFileParams.map((params) => {\n const a: [Set<string> | (() => boolean), LangPackKey, ChatRights][] = [\n [AUDIO_MIME_TYPES_SUPPORTED, 'GlobalAttachAudioRestricted', 'send_audios'],\n [() => !MEDIA_MIME_TYPES_SUPPORTED.has(params.file.type), 'GlobalAttachDocumentsRestricted', 'send_docs']\n ];\n\n if(isMedia) {\n a.unshift(\n [IMAGE_MIME_TYPES_SUPPORTED, 'GlobalAttachPhotoRestricted', 'send_photos'],\n [() => VIDEO_MIME_TYPES_SUPPORTED.has(params.file.type as any) && params.noSound, 'GlobalAttachGifRestricted', 'send_gifs'],\n [VIDEO_MIME_TYPES_SUPPORTED, 'GlobalAttachVideoRestricted', 'send_videos']\n );\n }\n\n const found = a.find(([verify]) => {\n return typeof(verify) === 'function' ? verify() : verify.has(params.file.type);\n });\n\n if(found) {\n return canSend[found[2]] ? undefined : found[1];\n }\n\n return (!isMedia && !canSend.send_docs && 'GlobalAttachDocumentsRestricted') || undefined;\n });\n\n const key = isBad.find((i) => typeof(i) === 'string') as LangPackKey;\n if(key) {\n toastNew({\n langPackKey: key\n });\n\n if(liteMode.isAvailable('animations')) {\n shake(this.body);\n }\n }\n\n foundBad ||= !!key;\n });\n\n if(foundBad) {\n return;\n }\n\n if(this.chat.type === 'scheduled' && !force) {\n this.chat.input.scheduleSending(() => {\n this.send(true);\n });\n\n return;\n }\n\n const {length} = sendFileDetails;\n const sendingParams = this.chat.getMessageSendingParams();\n this.iterate((sendFileParams) => {\n if(caption && sendFileParams.length !== length) {\n this.managers.appMessagesManager.sendText(peerId, caption, {\n ...sendingParams,\n clearDraft: true\n });\n\n caption = undefined;\n }\n\n const d: SendFileDetails[] = sendFileParams.map((params) => {\n return {\n ...params,\n file: params.scaledBlob || params.file,\n spoiler: !!params.mediaSpoiler\n };\n });\n\n const w = {\n ...willAttach,\n sendFileDetails: d\n };\n\n this.managers.appMessagesManager.sendAlbum(peerId, Object.assign({\n ...sendingParams,\n caption,\n isMedia,\n clearDraft: true\n }, w));\n\n caption = undefined;\n });\n\n input.replyToMsgId = this.chat.threadId;\n input.onMessageSent();\n this.wasInputValue = undefined;\n\n this.hide();\n }\n\n private modifyMimeTypeForTelegram(mimeType: string) {\n return mimeType === 'image/webp' ? 'image/jpeg' : mimeType;\n }\n\n private async scaleImageForTelegram(image: HTMLImageElement, mimeType: string, convertWebp?: boolean) {\n const PHOTO_SIDE_LIMIT = 2560;\n let url = image.src, scaledBlob: Blob;\n if(\n mimeType !== 'image/gif' &&\n (Math.max(image.naturalWidth, image.naturalHeight) > PHOTO_SIDE_LIMIT || (convertWebp && mimeType === 'image/webp'))\n ) {\n const {blob} = await scaleMediaElement({\n media: image,\n boxSize: makeMediaSize(PHOTO_SIDE_LIMIT, PHOTO_SIDE_LIMIT),\n mediaSize: makeMediaSize(image.naturalWidth, image.naturalHeight),\n mimeType: this.modifyMimeTypeForTelegram(mimeType) as any\n });\n\n scaledBlob = blob;\n URL.revokeObjectURL(url);\n url = await apiManagerProxy.invoke('createObjectURL', blob);\n await renderImageFromUrlPromise(image, url);\n }\n\n return scaledBlob && {url, blob: scaledBlob};\n }\n\n private async attachMedia(params: SendFileParams) {\n const {itemDiv} = params;\n itemDiv.classList.add('popup-item-media');\n\n const file = params.file;\n const isVideo = file.type.startsWith('video/');\n\n if(isVideo) {\n const video = createVideo();\n video.src = params.objectURL = await apiManagerProxy.invoke('createObjectURL', file);\n video.autoplay = true;\n video.controls = false;\n video.muted = true;\n\n video.addEventListener('timeupdate', () => {\n video.pause();\n }, {once: true});\n\n itemDiv.append(video);\n\n let error: Error;\n try {\n await onMediaLoad(video);\n } catch(err) {\n error = err as any;\n }\n\n params.width = video.videoWidth;\n params.height = video.videoHeight;\n params.duration = Math.floor(video.duration);\n\n if(error) {\n throw error;\n }\n\n const audioDecodedByteCount = (video as any).webkitAudioDecodedByteCount;\n if(audioDecodedByteCount !== undefined) {\n params.noSound = !audioDecodedByteCount;\n }\n\n const thumb = await createPosterFromVideo(video);\n params.thumb = {\n url: await apiManagerProxy.invoke('createObjectURL', thumb.blob),\n ...thumb\n };\n } else {\n const img = new Image();\n itemDiv.append(img);\n const url = params.objectURL = await apiManagerProxy.invoke('createObjectURL', file);\n\n await renderImageFromUrlPromise(img, url);\n const mimeType = params.file.type;\n const scaled = await this.scaleImageForTelegram(img, mimeType, true);\n if(scaled) {\n params.objectURL = scaled.url;\n params.scaledBlob = scaled.blob;\n }\n\n params.width = img.naturalWidth;\n params.height = img.naturalHeight;\n\n if(file.type === 'image/gif') {\n params.noSound = true;\n\n return Promise.all([\n getGifDuration(img).then((duration) => {\n params.duration = Math.ceil(duration);\n }),\n\n createPosterFromMedia(img).then(async(thumb) => {\n params.thumb = {\n url: await apiManagerProxy.invoke('createObjectURL', thumb.blob),\n ...thumb\n };\n })\n ]).then(() => {});\n }\n }\n }\n\n private async attachDocument(params: SendFileParams): ReturnType<PopupNewMedia['attachMedia']> {\n const {itemDiv} = params;\n itemDiv.classList.add('popup-item-document');\n const file = params.file;\n\n const isPhoto = file.type.startsWith('image/');\n const isAudio = AUDIO_MIME_TYPES_SUPPORTED.has(file.type as any);\n if(isPhoto || isAudio || file.size < 20e6) {\n params.objectURL ||= await apiManagerProxy.invoke('createObjectURL', file);\n }\n\n const attributes: DocumentAttribute[] = [];\n\n let img: HTMLImageElement;\n if(isPhoto && params.objectURL) {\n img = new Image();\n await renderImageFromUrlPromise(img, params.objectURL);\n const scaled = await this.scaleImageForTelegram(img, params.file.type);\n if(scaled) {\n params.objectURL = scaled.url;\n }\n }\n\n if(isAudio && params.objectURL) {\n try {\n // * get audio duration\n const audio = new Audio();\n audio.src = params.objectURL;\n audio.muted = true;\n audio.autoplay = true;\n await onMediaLoad(audio);\n params.duration = audio.duration;\n attributes.push({\n _: 'documentAttributeAudio',\n duration: params.duration,\n pFlags: {}\n });\n } catch(err) {\n console.error('audio loading error', err);\n }\n }\n\n const doc: MyDocument = {\n _: 'document',\n file,\n file_name: file.name || '',\n size: file.size,\n type: isAudio ? 'audio' : (isPhoto ? 'photo' : undefined),\n access_hash: 0,\n attributes,\n date: 0,\n dc_id: 0,\n file_reference: [],\n id: 0,\n pFlags: {},\n duration: params.duration\n };\n\n let cacheContext: ThumbCache;\n if(params.objectURL) {\n cacheContext = {\n url: params.objectURL,\n downloaded: file.size,\n type: THUMB_TYPE_FULL\n };\n }\n\n const docDiv = await wrapDocument({\n message: {\n _: 'message',\n pFlags: {\n is_outgoing: true\n },\n mid: 0,\n peerId: 0,\n media: {\n _: 'messageMediaDocument',\n document: doc\n }\n } as any,\n cacheContext\n });\n\n if(isPhoto) {\n params.width = img.naturalWidth;\n params.height = img.naturalHeight;\n }\n\n itemDiv.append(docDiv);\n }\n\n private attachFile = (file: File) => {\n const willAttach = this.willAttach;\n const shouldCompress = this.shouldCompress(file.type);\n\n const itemDiv = document.createElement('div');\n itemDiv.classList.add('popup-item');\n\n const params: SendFileParams = {\n file\n } as any;\n\n // do not pass these properties to worker\n defineNotNumerableProperties(params, ['scaledBlob', 'middlewareHelper', 'itemDiv', 'mediaSpoiler']);\n\n params.middlewareHelper = this.middlewareHelper.get().create();\n params.itemDiv = itemDiv;\n\n const promise = shouldCompress ? this.attachMedia(params) : this.attachDocument(params);\n willAttach.sendFileDetails.push(params);\n return promise.catch((err) => {\n itemDiv.style.backgroundColor = '#000';\n console.error('error rendering file', err);\n });\n };\n\n private shouldCompress(mimeType: string) {\n return this.willAttach.type === 'media' && MEDIA_MIME_TYPES_SUPPORTED.has(mimeType);\n }\n\n private onRender() {\n // show now\n if(!this.element.classList.contains('active')) {\n this.listenerSetter.add(document.body)('keydown', this.onKeyDown);\n !this.ignoreInputValue && this.addEventListener('close', () => {\n if(this.wasInputValue) {\n this.chat.input.messageInputField.value = this.wasInputValue;\n }\n });\n this.show();\n }\n }\n\n private setTitle() {\n const {willAttach, title, files} = this;\n let key: LangPackKey;\n const args: FormatterArguments = [];\n if(willAttach.type === 'document') {\n key = 'PreviewSender.SendFile';\n args.push(files.length);\n } else {\n let foundPhotos = 0, foundVideos = 0, foundFiles = 0;\n files.forEach((file) => {\n if(file.type.startsWith('image/')) ++foundPhotos;\n else if(file.type.startsWith('video/')) ++foundVideos;\n else ++foundFiles;\n });\n\n if([foundPhotos, foundVideos, foundFiles].filter((n) => n > 0).length > 1) {\n key = 'PreviewSender.SendFile';\n args.push(files.length);\n } else\n\n /* const sum = foundPhotos + foundVideos;\n if(sum > 1 && willAttach.group) {\n key = 'PreviewSender.SendAlbum';\n const albumsLength = Math.ceil(sum / 10);\n args.push(albumsLength);\n } else */if(foundPhotos) {\n key = 'PreviewSender.SendPhoto';\n args.push(foundPhotos);\n } else if(foundVideos) {\n key = 'PreviewSender.SendVideo';\n args.push(foundVideos);\n }\n }\n\n replaceContent(title, i18n(key, args));\n }\n\n private appendMediaToContainer(params: SendFileParams) {\n if(this.shouldCompress(params.file.type)) {\n const size = calcImageInBox(params.width, params.height, MAX_WIDTH, 320);\n params.itemDiv.style.width = size.width + 'px';\n params.itemDiv.style.height = size.height + 'px';\n }\n\n this.mediaContainer.append(params.itemDiv);\n }\n\n private iterate(cb: (sendFileDetails: SendFileParams[]) => void) {\n const {sendFileDetails} = this.willAttach;\n if(!this.willAttach.group) {\n sendFileDetails.forEach((p) => cb([p]));\n return;\n }\n\n const length = sendFileDetails.length;\n for(let i = 0; i < length;) {\n const firstType = sendFileDetails[i].file.type;\n let k = 0;\n for(; k < 10 && i < length; ++i, ++k) {\n const type = sendFileDetails[i].file.type;\n if(this.shouldCompress(firstType) !== this.shouldCompress(type)) {\n break;\n }\n }\n\n cb(sendFileDetails.slice(i - k, i));\n }\n }\n\n private attachFiles() {\n const {files, willAttach, mediaContainer} = this;\n\n const oldSendFileDetails = willAttach.sendFileDetails.splice(0, willAttach.sendFileDetails.length);\n oldSendFileDetails.forEach((params) => {\n params.middlewareHelper.destroy();\n });\n\n const promises = files.map((file) => this.attachFile(file));\n\n Promise.all(promises).then(() => {\n mediaContainer.replaceChildren();\n\n if(!files.length) {\n return;\n }\n\n this.setTitle();\n\n this.iterate((sendFileDetails) => {\n const shouldCompress = this.shouldCompress(sendFileDetails[0].file.type);\n if(shouldCompress && sendFileDetails.length > 1) {\n const albumContainer = document.createElement('div');\n albumContainer.classList.add('popup-item-album', 'popup-item');\n albumContainer.append(...sendFileDetails.map((s) => s.itemDiv));\n\n prepareAlbum({\n container: albumContainer,\n items: sendFileDetails.map((o) => ({w: o.width, h: o.height})),\n maxWidth: MAX_WIDTH,\n minWidth: 100,\n spacing: 4\n });\n\n mediaContainer.append(albumContainer);\n } else {\n sendFileDetails.forEach((params) => {\n this.appendMediaToContainer(params);\n });\n }\n\n if(!shouldCompress) {\n return;\n }\n\n sendFileDetails.forEach((params) => {\n const oldParams = oldSendFileDetails.find((o) => o.file === params.file);\n if(!oldParams) {\n return;\n }\n\n if(oldParams.mediaSpoiler) {\n this.applyMediaSpoiler(params, true);\n }\n });\n });\n }).then(() => {\n this.onRender();\n this.onScroll();\n });\n }\n}\n\n(window as any).PopupNewMedia = PopupNewMedia;\n","function cacheCallback<A, T>(callback: (str: A) => T) {\n const stringResults: any = {}, numberResults: any = {};\n return (value: A): T => {\n const key = '_' + value;\n return (typeof(value) === 'string' ? stringResults : numberResults)[key] ??= callback(value);\n };\n}\n\nexport default cacheCallback;\n","export default function replaceNonNumber(str: string) {\n return str.replace(/\\D/g, '');\n}\n","import cacheCallback from '../cacheCallback';\nimport replaceNonNumber from '../string/replaceNonNumber';\n\nconst CARD_BRAND_REGEXP: {[brand: string]: RegExp} = {\n visa: /^4/,\n mastercard: /^(51|52|53|54|55|222|23|24|25|26|27)/,\n amex: /^(34|37)/,\n discover: /^(60|64|65)/,\n diners: /^(30|38|39)/,\n diners14: /^(36)/,\n jcb: /^(35)/,\n unionpay: /^(62[0-6,8-9]|627[0-6,8-9]|6277[0-7,9]|62778[1-9]|81)/,\n elo: /^(5067|509|636368|627780)/,\n mir: /^(220[0-4])/\n};\n\n// * taken from Stripe\nexport const CARD_BRANDS: {[b: string]: {\n minLength: number,\n maxLength: number,\n cvcMaxLength: number,\n cvcMinLength: number | null\n}} = {\n visa: {\n minLength: 16,\n maxLength: 16,\n cvcMaxLength: 3,\n cvcMinLength: null\n },\n mastercard: {\n minLength: 16,\n maxLength: 16,\n cvcMaxLength: 3,\n cvcMinLength: null\n },\n amex: {\n minLength: 15,\n maxLength: 15,\n cvcMaxLength: 4,\n cvcMinLength: 3\n },\n unionpay: {\n minLength: 13,\n maxLength: 19,\n cvcMaxLength: 3,\n cvcMinLength: null\n },\n diners: {\n minLength: 16,\n maxLength: 16,\n cvcMaxLength: 3,\n cvcMinLength: null\n },\n diners14: {\n minLength: 14,\n maxLength: 14,\n cvcMaxLength: 3,\n cvcMinLength: null\n },\n discover: {\n minLength: 16,\n maxLength: 16,\n cvcMaxLength: 3,\n cvcMinLength: null\n },\n jcb: {\n minLength: 16,\n maxLength: 16,\n cvcMaxLength: 3,\n cvcMinLength: null\n },\n elo: {\n minLength: 16,\n maxLength: 16,\n cvcMaxLength: 3,\n cvcMinLength: null\n },\n mir: {\n minLength: 16,\n maxLength: 16,\n cvcMaxLength: 3,\n cvcMinLength: null\n },\n unknown: {\n minLength: 16,\n maxLength: 16,\n cvcMaxLength: 4,\n cvcMinLength: 3\n }\n};\n\nexport const detectCardBrand = cacheCallback((card: string = '') => {\n const keys = Object.keys(CARD_BRAND_REGEXP);\n const sanitizedCard = replaceNonNumber(card);\n let brand: string;\n let last = 0;\n keys.forEach((key) => {\n const regExp = CARD_BRAND_REGEXP[key];\n const match = sanitizedCard.match(regExp);\n if(match) {\n const result = match[0];\n if(result && result.length > last) {\n brand = key;\n last = result.length;\n }\n }\n });\n\n return brand || 'unknown';\n});\n\nexport function cardBrandToUnifiedBrand(brand: string) {\n return brand === 'diners14' ? 'diners' : brand;\n}\n\nexport function detectUnifiedCardBrand(card = '') {\n const brand = detectCardBrand(card);\n return cardBrandToUnifiedBrand(brand);\n}\n","export default function createArray<T1>(length: number, fill?: T1, map?: any): T1[] {\n const arr = new Array<T1>(length);\n arr.fill(fill);\n return map ? arr.map(map) : arr;\n}\n","const delta = ''.charCodeAt(0) - '0'.charCodeAt(0);\nconst buggedRegExp = /[-]/g;\n\n// function hasBuggedNumbers(str: string) {\n// return !!str.match(a);\n// }\n\nfunction getDistanceFromBuggedToNormal(char: string) {\n return String.fromCharCode(char.charCodeAt(0) - delta);\n}\n\nexport function fixBuggedNumbers(str: string) {\n return str.replace(buggedRegExp, getDistanceFromBuggedToNormal);\n}\n","import {fixBuggedNumbers} from '../string/buggedNumbers';\nimport replaceNonNumber from '../string/replaceNonNumber';\n\nexport type PatternCharacter = {\n type: 'optional',\n result: string,\n consumed: number\n} | {\n type: 'required',\n result: string,\n consumed: number,\n partial?: boolean\n} | {\n type: 'formatting',\n result: string,\n consumed: number\n};\n\nexport type PatternFunction = (str: string) => ((str: string) => PatternCharacter)[];\n\nfunction makeOptionalCharacter(result: string, consumed: number): PatternCharacter {\n return {type: 'optional', result, consumed};\n}\n\nfunction makeRequiredCharacter(result: string, consumed: number, partial?: boolean): PatternCharacter {\n return {type: 'required', result, consumed, partial};\n}\n\nfunction makeFormattingCharacter(result: string, consumed: number): PatternCharacter {\n return {type: 'formatting', result, consumed};\n}\n\nfunction wrapCharacterRegExpFactory(regExp: RegExp, optional?: boolean) {\n return (str: string) => {\n const _regExp = new RegExp('^'.concat(regExp.source.replace(/^\\^/, '')));\n const match = str.match(_regExp);\n const makeCharacter = optional ? makeOptionalCharacter : makeRequiredCharacter;\n if(match) {\n const result = match[0];\n return makeCharacter(result, match.index + result.length);\n }\n\n return makeCharacter('', str.length);\n };\n}\n\nfunction makeCapitalPatternCharacter(str: string) {\n const char = wrapCharacterRegExpFactory(/\\w/)(str);\n return char.result ? makeRequiredCharacter(char.result.toUpperCase(), char.consumed) : char;\n}\n\nconst makeMonthDigitPatternCharacter = wrapCharacterRegExpFactory(/1[0-2]|0?[1-9]|0/);\n\nfunction digit(str: string) {\n return wrapCharacterRegExpFactory(/[0-9]/)(fixBuggedNumbers(str));\n}\n\nconst patternCharacters = {\n digit,\n capitalCharacter: makeCapitalPatternCharacter,\n month: (str: string) => {\n const char = makeMonthDigitPatternCharacter(fixBuggedNumbers(str));\n const cleanedResult = replaceNonNumber(char.result);\n const isPartial = ['0', '1'].includes(char.result) && str.length === 1;\n if(isPartial || (char.result === '0' && str.length >= 2)) {\n return makeRequiredCharacter(char.result, str.length, true);\n }\n\n return makeRequiredCharacter(cleanedResult.length === 1 ? '0' + cleanedResult : cleanedResult, char.consumed);\n },\n formattingCharacter: (str: string) => {\n return (str1: string) => {\n const consumed = str === str1[0] ? 1 : 0;\n return makeFormattingCharacter(str, consumed);\n }\n },\n optionalPattern: (regExp: RegExp) => {\n return (str: string) => {\n const char = wrapCharacterRegExpFactory(regExp, true)(str);\n return char.result ? char : makeOptionalCharacter('', 0);\n };\n }\n};\n\nexport default patternCharacters;\n","import {IS_ANDROID} from '../../environment/userAgent';\nimport createArray from '../array/createArray';\nimport cacheCallback from '../cacheCallback';\nimport replaceNonNumber from '../string/replaceNonNumber';\nimport {CARD_BRANDS, detectCardBrand} from './cardBrands';\nimport patternCharacters from './patternCharacters';\n\nconst digit = patternCharacters.digit;\nconst capitalCharacter = patternCharacters.capitalCharacter;\nconst spaceCharacter = patternCharacters.formattingCharacter(' ');\nconst yearOptionalPattern = patternCharacters.optionalPattern(/\\d\\d/);\nconst sixteenPattern = [digit, digit, digit, digit, spaceCharacter, digit, digit, digit, digit, digit, digit, spaceCharacter, digit, digit, digit, digit, digit];\nconst fifteenPattern = [digit, digit, digit, digit, spaceCharacter, digit, digit, digit, digit, digit, digit, spaceCharacter, digit, digit, digit, digit];\n\nconst requiredPostcodes = new Set(['DZ', 'AR', 'AM', 'AU', 'AT', 'AZ', 'PT', 'BD', 'BY', 'BE', 'BA', 'BR', 'BN', 'BG', 'CA', 'IC', 'CN', 'CO', 'HR', 'CY', 'CZ', 'DK', 'EC', 'GB', 'EE', 'FO', 'FI', 'FR', 'GE', 'DE', 'GR', 'GL', 'GU', 'GG', 'NL', 'HU', 'IN', 'ID', 'IL', 'IT', 'JP', 'JE', 'KZ', 'KR', 'FM', 'KG', 'LV', 'LI', 'LT', 'LU', 'MK', 'MG', 'PT', 'MY', 'MH', 'MQ', 'YT', 'MX', 'MN', 'ME', 'NL', 'NZ', 'GB', 'NO', 'PK', 'PH', 'PL', 'FM', 'PT', 'PR', 'RE', 'RU', 'SA', 'SF', 'RS', 'SG', 'SK', 'SI', 'ZA', 'ES', 'LK', 'SX', 'VI', 'VI', 'SE', 'CH', 'TW', 'TJ', 'TH', 'TU', 'TN', 'TR', 'TM', 'VI', 'UA', 'GB', 'US', 'UY', 'UZ', 'VA', 'VN', 'GB', 'FM']);\n\nconst generateFourPattern = cacheCallback((length: number) => {\n const out: Array<typeof digit | typeof spaceCharacter> = [];\n\n for(let i = 0, k = 0; i < length;) {\n if(k === 4) {\n out.push(spaceCharacter);\n k = 0;\n } else {\n out.push(digit);\n ++i;\n ++k;\n }\n }\n\n return out;\n});\n\nfunction generateCardNumberPattern(card: string) {\n const brand = detectCardBrand(card);\n if(brand === 'amex') return sixteenPattern;\n if(brand === 'diners14') return fifteenPattern;\n const {minLength, maxLength} = CARD_BRANDS[brand];\n const s = replaceNonNumber(card).length;\n const d = Math.min(Math.max(minLength, s), maxLength);\n return generateFourPattern(d);\n}\n\nconst cardFormattingPatterns = {\n cardNumber: generateCardNumberPattern,\n cardExpiry: () => [patternCharacters.month, patternCharacters.formattingCharacter('/'), digit, digit, yearOptionalPattern],\n cardCvc: (card?: string) => cardFormattingPatterns.cardCvcFromBrand(detectCardBrand(card)),\n cardCvcFromBrand: cacheCallback((brand: string) => {\n const info = CARD_BRANDS[brand];\n const {cvcMinLength, cvcMaxLength} = info;\n const pattern = createArray(cvcMinLength || cvcMaxLength, digit);\n if(cvcMinLength && cvcMinLength < cvcMaxLength) {\n const i = cvcMaxLength - cvcMinLength;\n const h = patternCharacters.optionalPattern(/\\d/);\n if(i) {\n pattern.push(...createArray(i, h));\n }\n }\n\n return pattern;\n }),\n postalCodeFromCountry: cacheCallback((iso2: string) => {\n switch(iso2) {\n case 'US':\n return createArray(5, digit);\n case 'CA':\n return IS_ANDROID ? null : [capitalCharacter, capitalCharacter, capitalCharacter, spaceCharacter, capitalCharacter, capitalCharacter, capitalCharacter];\n default:\n const optionalDigits = createArray(10, patternCharacters.optionalPattern(/\\d/));\n if(requiredPostcodes.has(iso2)) {\n optionalDigits[0] = digit;\n }\n return optionalDigits;\n }\n })\n};\n\nexport default cardFormattingPatterns;\n","import accumulate from '../array/accumulate';\nimport {PatternFunction} from './patternCharacters';\n\nfunction accumulateLengths(strs: string[]) {\n return accumulate(strs.map((str) => str.length), 0);\n}\n\nfunction formatValueByPattern(\n getPattern: PatternFunction,\n value: string,\n options: Partial<{\n selectionStart: number,\n selectionEnd: number\n }> = {},\n pushRest?: boolean\n) {\n const pattern = getPattern(value);\n\n if(!pattern) {\n return {\n value: value,\n selection: null as typeof options,\n autocorrectComplete: !!value\n };\n }\n\n const length = pattern.length;\n const c: string[] = [];\n const s: string[] = [];\n\n let l = 0;\n let i = 0;\n let f = options.selectionStart === 0 ? 0 : null;\n let d = options.selectionEnd === 0 ? 0 : null;\n const p = () => {\n if(f === null && (i + 1) >= options.selectionStart) f = accumulateLengths(c) + (pushRest ? s.length : 0);\n if(d === null && (i + 1) >= options.selectionEnd) d = accumulateLengths(c) + (pushRest ? s.length : 0);\n };\n const m = (e: number) => {\n if(e > 0) {\n p();\n i += e;\n }\n };\n\n for(; l < length;) {\n const getCharacter = pattern[l];\n const character = getCharacter(value.slice(i));\n const {type, result, consumed} = character;\n if(type === 'required') {\n if(result) {\n c.push(...s, result);\n s.length = 0;\n ++l;\n\n if(character.partial) {\n m(value.length - i);\n break;\n }\n\n m(consumed);\n } else {\n if(!consumed) {\n break;\n }\n\n m(1);\n }\n } else if(type === 'optional') {\n if(result) {\n c.push(...s, result);\n s.length = 0;\n m(consumed);\n }\n\n ++l;\n } else if(type === 'formatting') {\n if(!pushRest && i >= value.length) {\n break;\n }\n\n s.push(result);\n ++l;\n m(consumed);\n }\n }\n\n if(pushRest) {\n c.push(...s);\n }\n\n return {\n value: c.join(''),\n selection: {\n selectionStart: f === null || value.length && options.selectionStart === value.length ? accumulateLengths(c) : f,\n selectionEnd: d === null || value.length && options.selectionEnd === value.length ? accumulateLengths(c) : d\n },\n autocorrectComplete: l === length\n };\n}\n\nexport default formatValueByPattern;\n","import {CARD_BRANDS, detectCardBrand} from './cardBrands';\nimport formatInputValueByPattern from './formatInputValueByPattern';\nimport NBSP from '../string/nbsp';\nimport replaceNonNumber from '../string/replaceNonNumber';\n\nexport type PatternValidationOptions = Partial<{\n ignoreIncomplete: boolean\n}>;\n\nconst nbspRegExp = new RegExp(NBSP, 'g');\n\nfunction makeValidationError(code?: string) {\n return code ? {\n type: 'invalid',\n code\n } : null;\n}\n\n// Luhn algorithm\nfunction validateCompleteCardNumber(card: string) {\n const t = '0'.charCodeAt(0);\n const n = card.length % 2;\n let a = 0;\n for(let i = card.length - 1; i >= 0; --i) {\n const c = n === (i % 2);\n let o = card.charCodeAt(i) - t;\n if(c) o *= 2;\n if(o > 9) o -= 9;\n a += o;\n }\n return !(a % 10);\n}\n\nfunction validateExpiry(year: number, month: number, options?: PatternValidationOptions) {\n const date = new Date(Date.now());\n const _year = year < 100 ? date.getFullYear() % 100 : date.getFullYear();\n const nextMonth = date.getMonth() + 1;\n\n if(isNaN(year) || isNaN(month)) {\n return options?.ignoreIncomplete ? null : 'incomplete';\n }\n\n if((year - _year) < 0) {\n return 'invalid_expiry_year_past';\n }\n\n if((year - _year) > 50) {\n return 'invalid_expiry_year';\n }\n\n return !(year - _year) && month < nextMonth ? 'invalid_expiry_month_past' : null;\n}\n\nfunction getCardInfoByNumber(card: string) {\n const sanitized = replaceNonNumber(card);\n const brand = detectCardBrand(card);\n return {\n sanitized,\n brand,\n minLength: CARD_BRANDS[brand].minLength\n };\n}\n\nfunction makeCardNumberError(str: string, length: number, ignoreIncomplete: boolean) {\n if(str.length >= length) {\n return validateCompleteCardNumber(str) || detectCardBrand(str) === 'mir' ? null : makeValidationError('invalid');\n }\n\n return ignoreIncomplete ? null : makeValidationError('incomplete');\n}\n\nexport function validateCardNumber(str: string, options: PatternValidationOptions = {}) {\n const {sanitized, minLength} = getCardInfoByNumber(str);\n return makeCardNumberError(sanitized, minLength, options.ignoreIncomplete);\n}\n\nexport function validateCardExpiry(str: string, options: PatternValidationOptions = {}) {\n const sanitized = str.replace(nbspRegExp, '').split(/ ?\\/ ?/);\n const [monthStr, yearStr = ''] = sanitized;\n const [month, year] = [monthStr, yearStr].map((str) => +str);\n const s = yearStr.length === 2 ? year % 100 : year;\n return yearStr.length < 2 || yearStr.length === 3 ? (options.ignoreIncomplete ? null : makeValidationError('incomplete')) : makeValidationError(validateExpiry(s, month, options));\n}\n\nexport function validateAnyIncomplete(formatted: ReturnType<typeof formatInputValueByPattern>, str: string, options: PatternValidationOptions = {}) {\n return formatted.meta.autocorrectComplete || options.ignoreIncomplete ? null : makeValidationError('incomplete');\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '.';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport TelegramWebView from '../telegramWebView';\n\nexport function createVerificationIframe(options: ConstructorParameters<typeof TelegramWebView>[0]) {\n const result = new TelegramWebView({\n ...options,\n sandbox: 'allow-forms allow-scripts allow-same-origin allow-modals'\n });\n const {iframe} = result;\n iframe.allow = 'payment';\n iframe.classList.add('payment-verification');\n return result;\n}\n\nexport default class PopupPaymentVerification extends PopupElement<{\n finish: () => void\n}> {\n private telegramWebView: TelegramWebView;\n\n constructor(private url: string, private openPathAfter?: boolean) {\n super('popup-payment popup-payment-verification', {\n closable: true,\n overlayClosable: true,\n body: true,\n title: 'Checkout.WebConfirmation.Title'\n });\n\n this.d();\n }\n\n private d() {\n const telegramWebView = this.telegramWebView = createVerificationIframe({\n url: this.url\n });\n\n telegramWebView.addEventListener('web_app_open_tg_link', (e) => {\n this.dispatchEvent('finish');\n this.hide();\n if(this.openPathAfter) {\n appImManager.openUrl('https://t.me' + e.path_full);\n }\n });\n\n this.body.append(telegramWebView.iframe);\n this.show();\n telegramWebView.onMount();\n }\n\n protected destroy() {\n this.telegramWebView.destroy();\n return super.destroy();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '.';\nimport cardFormattingPatterns from '../../helpers/cards/cardFormattingPatterns';\nimport {detectUnifiedCardBrand} from '../../helpers/cards/cardBrands';\nimport formatInputValueByPattern from '../../helpers/cards/formatInputValueByPattern';\nimport {validateAnyIncomplete, validateCardExpiry, validateCardNumber} from '../../helpers/cards/validateCard';\nimport placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd';\nimport {renderImageFromUrlPromise} from '../../helpers/dom/renderImageFromUrl';\nimport noop from '../../helpers/noop';\nimport {PaymentsPaymentForm} from '../../layer';\nimport {LangPackKey, _i18n} from '../../lib/langPack';\nimport CheckboxField from '../checkboxField';\nimport confirmationPopup from '../confirmationPopup';\nimport CountryInputField from '../countryInputField';\nimport InputField, {InputFieldOptions, InputState} from '../inputField';\nimport Row from '../row';\nimport {getPaymentBrandIconPath, PaymentButton, PaymentsCredentialsToken} from './payment';\nimport {createVerificationIframe} from './paymentVerification';\nimport {PasswordInputHelpers} from '../passwordInputField';\nimport SettingSection from '../settingSection';\nimport TelegramWebView from '../telegramWebView';\n\nexport type PaymentCardDetails = {\n cardNumber: string;\n cardholderName: string;\n expiryFull: string;\n expiryMonth: string;\n expiryYear: string;\n cvc: string;\n country: string;\n zip: string;\n save?: boolean;\n};\n\nexport type PaymentCardDetailsShort = {\n title: string,\n save?: boolean;\n icon?: string;\n};\n\nexport type PaymentCardDetailsResult = PaymentCardDetails | PaymentCardDetailsShort;\n\nexport class InputFieldCorrected extends InputField {\n private lastKeyDown: string;\n private lastTransformed: ReturnType<typeof formatInputValueByPattern>;\n\n constructor(public options: InputFieldOptions & {\n formatMethod: typeof cardFormattingPatterns['cardNumber'],\n validateMethod?: typeof validateCardNumber,\n errorKeys?: {[code: string]: LangPackKey},\n optional?: boolean,\n onChange?: (transformed: InputFieldCorrected['lastTransformed']) => void,\n onKeyDown?: (e: KeyboardEvent) => void\n }) {\n super(options);\n\n // const handleIncomplete = (t?: any) => {\n // if(\n // (!lastTransformed.value && t) ||\n // lastTransformed.meta.autocorrectComplete ||\n // lastTransformed.meta.error ||\n // optional\n // ) {\n // return;\n // }\n\n\n // };\n\n this.input.addEventListener('keydown', this.onKeyDown);\n this.input.addEventListener('input', this.onInput);\n this.input.addEventListener('blur', this.onBlur);\n }\n\n private onKeyDown = (e: KeyboardEvent) => {\n this.lastKeyDown = e.key;\n this.options.onKeyDown?.(e);\n };\n\n private onInput = () => {\n const value = this.value;\n const deleting = this.lastKeyDown === 'Backspace' && (((this.lastTransformed && this.lastTransformed.value.length) || 0) - value.length) === 1;\n const result = this.lastTransformed = formatInputValueByPattern({\n value: value,\n getPattern: this.options.formatMethod,\n deleting,\n input: this.input\n });\n\n const transformedValue = result.value;\n if(transformedValue !== value) {\n this.setValueSilently(transformedValue);\n\n if(result.selection) {\n (this.input as HTMLInputElement).selectionStart = result.selection.selectionStart;\n (this.input as HTMLInputElement).selectionEnd = result.selection.selectionEnd;\n }\n }\n\n this.validateNew(transformedValue, {ignoreIncomplete: true/* !result.meta.autocorrectComplete */});\n\n this.options.onChange?.(result);\n };\n\n private onBlur = () => {\n const value = this.lastTransformed?.value;\n if(value) {\n this.validateNew(value);\n }\n };\n\n public update() {\n this.onInput();\n }\n\n public validate = () => {\n return this.validateNew();\n };\n\n public validateNew(\n value = this.lastTransformed?.value ?? '',\n t: any = {},\n justReturn?: boolean\n ) {\n let result: ReturnType<InputFieldCorrected['options']['validateMethod']>;\n if(this.options.validateMethod) {\n result = this.options.validateMethod?.(value, t);\n } else {\n result = validateAnyIncomplete(this.lastTransformed, value, t);\n }\n\n if(result?.code) {\n const langPackKey: LangPackKey = this.options.errorKeys?.[result.code];\n !justReturn && this.setState(InputState.Error, langPackKey);\n return false;\n }\n\n !justReturn && this.setState(InputState.Neutral);\n return true;\n }\n}\n\nexport function handleInputFieldsOnChange(inputFields: (CountryInputField | InputField | InputFieldCorrected)[], _onChange: (valid: boolean) => void) {\n const onChange = () => {\n const valid = inputFields.every((inputField) => {\n return 'validateNew' in inputField ? inputField.validateNew(undefined, undefined, true) : inputField.isValid();\n });\n\n _onChange(valid);\n };\n\n inputFields.forEach((inputField) => {\n if(inputField instanceof InputFieldCorrected) {\n const original = inputField.options.onChange;\n inputField.options.onChange = (...args: any[]) => {\n // @ts-ignore\n original?.(...args);\n onChange();\n };\n\n if('update' in inputField) {\n inputField.update();\n }\n } else {\n inputField.input.addEventListener('input', onChange);\n }\n });\n\n return {validate: onChange};\n}\n\nexport function createCountryZipFields(country?: boolean, zip?: boolean) {\n let countryInputField: CountryInputField, postcodeInputField: InputFieldCorrected;\n if(country || zip) {\n if(country) countryInputField = new CountryInputField({\n noPhoneCodes: true,\n onCountryChange: () => {\n postcodeInputField?.update();\n },\n required: true,\n autocomplete: 'country'\n });\n if(zip) postcodeInputField = new InputFieldCorrected({\n label: 'PaymentShippingZipPlaceholder',\n plainText: true,\n inputMode: 'numeric',\n autocomplete: 'postal-code',\n formatMethod: (/* ...args */) => {\n const {country} = countryInputField.getSelected();\n const iso2 = country?.iso2;\n return cardFormattingPatterns.postalCodeFromCountry(iso2 && iso2.toUpperCase());\n }\n });\n }\n\n return {countryInputField, postcodeInputField};\n}\n\nexport type PaymentsNativeProvider = 'stripe' | 'smartglocal';\nexport type PaymentsNativeParams = {\n need_country?: boolean,\n need_zip?: boolean,\n need_cardholder_name?: boolean,\n publishable_key?: string, // stripe\n public_token?: string, // smartglocal\n gpay_params: string,\n};\nconst SUPPORTED_NATIVE_PROVIDERS: Set<PaymentsNativeProvider> = new Set(['stripe', 'smartglocal']);\n\nexport default class PopupPaymentCard extends PopupElement<{\n finish: (obj: {token: any, card: PaymentCardDetailsResult}) => void\n}> {\n protected telegramWebView: TelegramWebView;\n\n constructor(private paymentForm: PaymentsPaymentForm, private savedCard?: PaymentCardDetails) {\n super('popup-payment popup-payment-card', {\n closable: true,\n overlayClosable: true,\n body: true,\n scrollable: SUPPORTED_NATIVE_PROVIDERS.has(paymentForm.native_provider as PaymentsNativeProvider),\n title: 'PaymentCardInfo'\n });\n\n if(SUPPORTED_NATIVE_PROVIDERS.has(paymentForm.native_provider as PaymentsNativeProvider)) {\n this.d();\n } else {\n const telegramWebView = this.telegramWebView = createVerificationIframe({\n url: paymentForm.url\n });\n\n telegramWebView.addEventListener('payment_form_submit', (data) => {\n const cardOut = {title: data.title, save: false} as any as PaymentCardDetails;\n this.dispatchEvent('finish', {\n token: data.credentials,\n card: cardOut\n });\n\n this.hide();\n\n if(paymentForm.pFlags.can_save_credentials) {\n confirmationPopup({\n titleLangKey: 'PaymentCardSavePaymentInformation',\n descriptionLangKey: 'PaymentCardSavePaymentInformationInfoLine1',\n button: {\n langKey: 'Save'\n }\n }).then(() => {\n cardOut.save = true;\n }, noop);\n }\n });\n\n // putPreloader(this.body, true);\n this.body.append(telegramWebView.iframe);\n this.show();\n telegramWebView.onMount();\n }\n }\n\n protected destroy() {\n this.telegramWebView?.destroy();\n return super.destroy();\n }\n\n private d() {\n const savedCard = this.savedCard;\n const cardSection = new SettingSection({name: 'PaymentInfo.Card.Title', noDelimiter: true, noShadow: true});\n\n const nativeParams: PaymentsNativeParams = JSON.parse(this.paymentForm.native_params.data);\n\n let lastBrand: string, brandIconTempId = 0, lastBrandImg: HTMLImageElement;\n const setBrandIcon = (brand: string) => {\n if(lastBrand === brand) {\n return;\n }\n\n const tempId = ++brandIconTempId;\n lastBrand = brand;\n\n const path = getPaymentBrandIconPath(brand);\n if(!path) {\n if(lastBrandImg) {\n lastBrandImg.remove();\n lastBrandImg = undefined;\n }\n\n return;\n }\n\n const img = new Image();\n img.classList.add('input-field-icon');\n renderImageFromUrlPromise(img, path, false).then(() => {\n if(brandIconTempId !== tempId) {\n return;\n }\n\n if(lastBrandImg) {\n lastBrandImg.replaceWith(img);\n } else {\n cardInputField.container.append(img);\n }\n\n lastBrandImg = img;\n });\n };\n const cardInputField = new InputFieldCorrected({\n label: 'PaymentCardNumber',\n plainText: true,\n inputMode: 'numeric',\n autocomplete: 'cc-number',\n formatMethod: cardFormattingPatterns.cardNumber,\n validateMethod: validateCardNumber,\n errorKeys: {\n invalid: 'PaymentCard.Error.Invalid',\n incomplete: 'PaymentCard.Error.Incomplete'\n },\n onChange: (transformed) => {\n setBrandIcon(detectUnifiedCardBrand(transformed.value));\n cvcInputField.update(); // format cvc\n }\n });\n\n let nameInputField: InputField;\n if(nativeParams.need_cardholder_name) nameInputField = new InputField({\n label: 'Checkout.NewCard.CardholderNamePlaceholder',\n maxLength: 255,\n required: true,\n autocomplete: 'cc-name'\n });\n\n const expireInputField = new InputFieldCorrected({\n label: 'SecureId.Identity.Placeholder.ExpiryDate',\n plainText: true,\n inputMode: 'numeric',\n autocomplete: 'cc-exp',\n formatMethod: cardFormattingPatterns.cardExpiry,\n validateMethod: validateCardExpiry\n });\n\n // handle autocomplete: 01/2345 -> 01/45\n expireInputField.input.addEventListener('input', () => {\n let value = expireInputField.value;\n if(value.length < 5) {\n return;\n }\n\n const splitted = value.split('/');\n if(splitted[1].length !== 4) {\n return;\n }\n\n value = [splitted[0], splitted[1].slice(2)].join('/');\n expireInputField.setValueSilently(value);\n }, {capture: true});\n\n const cvcInputField = new InputFieldCorrected({\n labelText: 'CVC',\n plainText: true,\n inputMode: 'numeric',\n autocomplete: 'cc-csc',\n name: 'cvc',\n formatMethod: () => cardFormattingPatterns.cardCvc(cardInputField.value)\n // validateMethod: (...args) => _5AH3.a.cardCvc(cardInputField.value)(...args)\n });\n\n const passwordHelpers = new PasswordInputHelpers(cvcInputField.container, cvcInputField.input as HTMLInputElement);\n\n const switchFocusOrder: (InputFieldCorrected | InputField)[] = [\n cardInputField,\n expireInputField,\n cvcInputField,\n nameInputField\n ].filter(Boolean);\n switchFocusOrder.forEach((inputField) => {\n const onKeyDown = (e: KeyboardEvent) => {\n if(!inputField.value && e.key === 'Backspace') {\n const previousInputField = switchFocusOrder[switchFocusOrder.indexOf(inputField) - 1];\n if(previousInputField) {\n // previousInputField.value = previousInputField.value.slice(0, -1);\n placeCaretAtEnd(previousInputField.input, true);\n }\n }\n };\n\n if(inputField instanceof InputFieldCorrected) {\n inputField.options.onKeyDown = onKeyDown;\n\n const original = inputField.options.onChange;\n inputField.options.onChange = (transformed) => {\n original?.(transformed);\n\n if(document.activeElement === inputField.input && transformed.meta.autocorrectComplete) {\n for(let i = switchFocusOrder.indexOf(inputField), length = switchFocusOrder.length; i < length; ++i) {\n const nextInputField = switchFocusOrder[i];\n if(\n nextInputField instanceof InputFieldCorrected ?\n !nextInputField.validateNew(undefined, undefined, true) :\n !nextInputField.value\n ) {\n placeCaretAtEnd(nextInputField.input, true);\n break;\n }\n }\n }\n };\n } else {\n inputField.input.addEventListener('keydown', onKeyDown);\n }\n });\n\n const inputFieldsRow = document.createElement('div');\n inputFieldsRow.classList.add('input-fields-row');\n inputFieldsRow.append(expireInputField.container, cvcInputField.container);\n\n const form = document.createElement('form');\n form.append(...[\n cardInputField.container,\n inputFieldsRow,\n nameInputField?.container\n ].filter(Boolean))\n\n cardSection.content.append(form);\n\n let billingSection: SettingSection;\n // let saveCheckboxField: CheckboxField;\n const {countryInputField, postcodeInputField} = createCountryZipFields(nativeParams.need_country, nativeParams.need_zip);\n if(nativeParams.need_country || nativeParams.need_zip) {\n billingSection = new SettingSection({name: 'PaymentInfo.Billing.Title', noDelimiter: true, noShadow: true});\n\n // const inputFieldsRow2 = inputFieldsRow.cloneNode() as HTMLElement;\n // inputFieldsRow2.append(countryInputField.container, postcodeInputField.container);\n // billingSection.content.append(inputFieldsRow2);\n billingSection.content.append(...[countryInputField, postcodeInputField].filter(Boolean).map((i) => i.container));\n }\n\n const canSave = !!this.paymentForm.pFlags.can_save_credentials;\n const saveCheckboxField = new CheckboxField({\n text: 'PaymentCardSavePaymentInformation',\n checked: !!canSave\n });\n const saveRow = new Row({\n checkboxField: saveCheckboxField,\n subtitleLangKey: canSave ? 'PaymentCardSavePaymentInformationInfoLine1' : 'Checkout.2FA.Text'\n });\n\n if(!canSave) {\n saveRow.container.classList.add('is-disabled');\n }\n\n (billingSection || cardSection).content.append(saveRow.container);\n\n this.scrollable.append(...[cardSection, billingSection].filter(Boolean).map((s) => s.container));\n\n const payButton = PaymentButton({\n key: 'PaymentInfo.Done',\n onClick: async() => {\n const data: PaymentCardDetails = {\n cardNumber: cardInputField.value,\n expiryFull: expireInputField.value,\n expiryMonth: expireInputField.value.split('/')[0],\n expiryYear: expireInputField.value.split('/')[1],\n cvc: cvcInputField.value,\n\n cardholderName: nameInputField?.value,\n country: countryInputField?.value,\n zip: postcodeInputField?.value,\n\n save: saveCheckboxField?.checked\n };\n\n const nativeProvider: PaymentsNativeProvider = this.paymentForm.native_provider as any;\n let out: PaymentsCredentialsToken;\n if(nativeProvider === 'stripe') {\n const url = new URL('https://api.stripe.com/v1/tokens');\n url.search = new URLSearchParams({\n 'card[number]': data.cardNumber,\n 'card[exp_month]': data.expiryMonth,\n 'card[exp_year]': data.expiryYear,\n 'card[cvc]': data.cvc,\n 'card[address_zip]': data.zip,\n 'card[address_country]': data.country,\n 'card[name]': data.cardholderName\n }).toString();\n\n const response = await fetch(url.toString(), {\n method: 'POST',\n credentials: 'same-origin',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'Authorization': `Bearer ${nativeParams.publishable_key}`\n }\n });\n\n out = await response.json();\n } else if(nativeProvider === 'smartglocal') {\n const params = {\n card: {\n number: data.cardNumber.replace(/[^\\d]+/g, ''),\n expiration_month: data.expiryMonth,\n expiration_year: data.expiryYear,\n security_code: data.cvc.replace(/[^\\d]+/g, '')\n }\n };\n\n const url = /* DEBUG_PAYMENT_SMART_GLOCAL */false ?\n 'https://tgb-playground.smart-glocal.com/cds/v1/tokenize/card' :\n 'https://tgb.smart-glocal.com/cds/v1/tokenize/card';\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json',\n 'X-PUBLIC-TOKEN': nativeParams.public_token\n },\n body: JSON.stringify(params)\n });\n\n const json: { // smartglocal\n data: {\n info: {\n card_network: string,\n card_type: string,\n masked_card_number: string\n },\n token: string\n },\n status: 'ok'\n } = await response.json();\n\n out = {type: 'card', token: json.data.token}\n }\n\n this.dispatchEvent('finish', {token: out, card: data});\n this.hide();\n }\n });\n\n const inputFields = ([\n cardInputField,\n nameInputField,\n expireInputField,\n cvcInputField,\n countryInputField,\n postcodeInputField\n ] as const).filter(Boolean);\n handleInputFieldsOnChange(inputFields, (valid) => {\n payButton.disabled = !valid;\n // payButton.classList.toggle('btn-disabled', !valid);\n });\n\n if(savedCard) {\n cardInputField.value = savedCard.cardNumber;\n expireInputField.value = savedCard.expiryFull;\n cvcInputField.value = savedCard.cvc;\n nameInputField && (nameInputField.value = savedCard.cardholderName);\n countryInputField && (countryInputField.value = savedCard.country);\n postcodeInputField && (postcodeInputField.value = savedCard.zip);\n }\n\n this.body.append(this.btnConfirmOnEnter = payButton);\n\n this.show();\n\n if(!cardInputField.validateNew(undefined, undefined, true)) {\n placeCaretAtEnd(cardInputField.input);\n }\n }\n}\n","import formatValueByPattern from './formatValueByPattern';\n\nexport default function formatInputValueByPattern(options: {\n value: string,\n getPattern: Parameters<typeof formatValueByPattern>[0],\n deleting?: boolean,\n input?: HTMLElement\n}) {\n const {value: originalValue, getPattern, deleting, input} = options;\n const pushRest = !deleting && !!originalValue.length;\n const result = formatValueByPattern(getPattern, originalValue, {\n selectionStart: input ? (input as HTMLInputElement).selectionStart : 0,\n selectionEnd: input ? (input as HTMLInputElement).selectionEnd : 0\n }, pushRest)\n const {value, selection} = result;\n\n return {\n value,\n meta: {\n autocorrectComplete: result.autocorrectComplete,\n empty: !value\n },\n selection\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '.';\nimport placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd';\nimport {AccountPassword, AccountTmpPassword} from '../../layer';\nimport {InputState} from '../inputField';\nimport PasswordInputField from '../passwordInputField';\nimport SettingSection from '../settingSection';\nimport {PaymentButton} from './payment';\n\nexport default class PopupPaymentCardConfirmation extends PopupElement<{\n finish: (tmpPassword: AccountTmpPassword) => void\n}> {\n constructor(card: string, passwordState: AccountPassword) {\n super('popup-payment popup-payment-card-confirmation', {\n closable: true,\n overlayClosable: true,\n body: true,\n scrollable: true,\n title: 'Checkout.PasswordEntry.Title'\n });\n\n const section = new SettingSection({noDelimiter: true, noShadow: true, caption: 'Checkout.PasswordEntry.Text', captionArgs: [card]});\n const passwordInputField = new PasswordInputField({labelText: passwordState.hint});\n section.content.append(passwordInputField.container);\n this.scrollable.append(section.container);\n\n const onInput = () => {\n payButton.disabled = !passwordInputField.value;\n passwordInputField.setState(InputState.Neutral);\n };\n\n passwordInputField.input.addEventListener('input', onInput);\n\n const payButton = PaymentButton({\n key: 'Checkout.PasswordEntry.Pay',\n onClick: async() => {\n try {\n const inputCheckPassword = await this.managers.passwordManager.getInputCheckPassword(passwordInputField.value, passwordState);\n const tmpPassword = await this.managers.apiManager.invokeApi('account.getTmpPassword', {\n password: inputCheckPassword,\n period: 60\n });\n\n this.dispatchEvent('finish', tmpPassword);\n this.hide();\n } catch(err) {\n if((err as ApiError).type === 'PASSWORD_HASH_INVALID') {\n (err as ApiError).handled = true;\n passwordInputField.setError('PASSWORD_HASH_INVALID');\n }\n\n throw err;\n }\n }\n });\n this.body.append(this.btnConfirmOnEnter = payButton);\n\n onInput();\n\n this.show();\n\n placeCaretAtEnd(passwordInputField.input);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '.';\nimport placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd';\nimport {InputInvoice, PaymentRequestedInfo, PaymentsPaymentForm, PaymentsValidatedRequestedInfo} from '../../layer';\nimport matchEmail from '../../lib/richTextProcessor/matchEmail';\nimport CheckboxField from '../checkboxField';\nimport CountryInputField from '../countryInputField';\nimport InputField from '../inputField';\nimport Row from '../row';\nimport SettingSection from '../settingSection';\nimport TelInputField from '../telInputField';\nimport {PaymentButton} from './payment';\nimport {createCountryZipFields, handleInputFieldsOnChange, InputFieldCorrected} from './paymentCard';\n\nexport type PaymentShippingAddress = PaymentRequestedInfo;\n\ntype ShippingFocusField = 'name' | 'email' | 'phone';\n\nexport default class PopupPaymentShipping extends PopupElement<{\n finish: (o: {shippingAddress: PaymentShippingAddress, requestedInfo: PaymentsValidatedRequestedInfo}) => void\n}> {\n constructor(\n private paymentForm: PaymentsPaymentForm,\n private inputInvoice: InputInvoice,\n private focus?: ShippingFocusField\n ) {\n super('popup-payment popup-payment-shipping', {\n closable: true,\n overlayClosable: true,\n body: true,\n scrollable: true,\n title: 'PaymentShippingInfo'\n });\n\n this.d();\n }\n\n private d() {\n const paymentForm = this.paymentForm;\n const invoice = paymentForm.invoice;\n const savedInfo = this.paymentForm.saved_info;\n\n let addressSection: SettingSection,\n address1InputField: InputField,\n address2InputField: InputField,\n cityInputField: InputField,\n stateInputField: InputField,\n countryInputField: CountryInputField,\n postcodeInputField: InputFieldCorrected;\n if(invoice.pFlags.shipping_address_requested) {\n addressSection = new SettingSection({name: 'PaymentShippingAddress', noDelimiter: true, noShadow: true});\n address1InputField = new InputField({label: 'PaymentShippingAddress1Placeholder', maxLength: 64, required: true});\n address2InputField = new InputField({label: 'PaymentShippingAddress2Placeholder', maxLength: 64});\n cityInputField = new InputField({label: 'PaymentShippingCityPlaceholder', maxLength: 64, required: true});\n stateInputField = new InputField({label: 'PaymentShippingStatePlaceholder', maxLength: 64});\n const res = createCountryZipFields(true, true);\n countryInputField = res.countryInputField;\n postcodeInputField = res.postcodeInputField;\n\n addressSection.content.append(...[\n address1InputField,\n address2InputField,\n cityInputField,\n stateInputField,\n countryInputField,\n postcodeInputField\n ].filter(Boolean).map((inputField) => inputField.container));\n }\n\n let receiverSection: SettingSection;\n let nameInputField: InputField, emailInputField: InputField, telInputField: TelInputField;\n if([invoice.pFlags.name_requested, invoice.pFlags.email_requested, invoice.pFlags.phone_requested].includes(true)) {\n receiverSection = new SettingSection({name: 'PaymentShippingReceiver', noDelimiter: true, noShadow: true});\n\n const validateEmail = () => {\n const value = emailInputField.value;\n const match = matchEmail(value);\n if(!match || match[0].length !== value.length) {\n return false;\n }\n\n return true;\n };\n\n const validatePhone = () => {\n return !!telInputField.value.match(/\\d/);\n };\n\n if(invoice.pFlags.name_requested) nameInputField = new InputField({label: 'PaymentShippingName', maxLength: 256, required: true});\n if(invoice.pFlags.email_requested) emailInputField = new InputField({label: 'PaymentShippingEmailPlaceholder', maxLength: 64, required: true, validate: validateEmail});\n if(invoice.pFlags.phone_requested) telInputField = new TelInputField({required: true, validate: validatePhone});\n\n receiverSection.content.append(...[\n nameInputField,\n emailInputField,\n telInputField\n ].filter(Boolean).map((inputField) => inputField.container));\n }\n\n const saveCheckboxField = new CheckboxField({\n text: 'PaymentShippingSave',\n checked: true\n });\n const saveRow = new Row({\n checkboxField: saveCheckboxField,\n subtitleLangKey: 'PaymentShippingSaveInfo'\n });\n\n (receiverSection || addressSection).content.append(saveRow.container);\n\n this.scrollable.append(...[addressSection, receiverSection].filter(Boolean).map((section) => section.container));\n\n const payButton = PaymentButton({\n key: 'PaymentInfo.Done',\n onClick: async() => {\n const selectedCountry = countryInputField && countryInputField.getSelected().country;\n const data: PaymentShippingAddress = {\n _: 'paymentRequestedInfo',\n shipping_address: selectedCountry && {\n _: 'postAddress',\n street_line1: address1InputField.value,\n street_line2: address2InputField.value,\n city: cityInputField.value,\n state: stateInputField.value,\n // country: countryInputField.value,\n country_iso2: selectedCountry?.iso2,\n post_code: postcodeInputField.value\n },\n name: nameInputField?.value,\n email: emailInputField?.value,\n phone: telInputField?.value\n };\n\n try {\n const requestedInfo = await this.managers.appPaymentsManager.validateRequestedInfo(this.inputInvoice, data, saveCheckboxField?.checked);\n\n this.dispatchEvent('finish', {\n shippingAddress: data,\n requestedInfo\n });\n\n this.hide();\n } catch(err: any) {\n const errorMap: {[err: string]: InputField} = {\n ADDRESS_STREET_LINE1_INVALID: address1InputField,\n ADDRESS_STREET_LINE2_INVALID: address2InputField,\n ADDRESS_COUNTRY_INVALID: countryInputField,\n ADDRESS_CITY_INVALID: cityInputField,\n ADDRESS_STATE_INVALID: stateInputField,\n ADDRESS_POSTCODE_INVALID: postcodeInputField,\n\n REQ_INFO_NAME_INVALID: nameInputField,\n REQ_INFO_EMAIL_INVALID: emailInputField,\n REQ_INFO_PHONE_INVALID: telInputField\n };\n\n const inputField = errorMap[(err as ApiError).type];\n if(inputField) {\n inputField.setError();\n (err as any).handled = true;\n }\n\n throw err;\n }\n }\n });\n this.body.append(this.btnConfirmOnEnter = payButton);\n\n if(savedInfo) {\n const shippingAddress = savedInfo.shipping_address;\n if(shippingAddress) {\n address1InputField.value = shippingAddress.street_line1;\n address2InputField.value = shippingAddress.street_line2;\n cityInputField.value = shippingAddress.city;\n stateInputField.value = shippingAddress.state;\n countryInputField.selectCountryByIso2(shippingAddress.country_iso2);\n postcodeInputField.value = shippingAddress.post_code;\n }\n\n savedInfo.name && nameInputField && (nameInputField.value = savedInfo.name);\n savedInfo.email && emailInputField && (emailInputField.value = savedInfo.email);\n savedInfo.phone && telInputField && (telInputField.value = savedInfo.phone);\n }\n\n const {validate} = handleInputFieldsOnChange([\n address1InputField,\n address2InputField,\n cityInputField,\n stateInputField,\n countryInputField,\n postcodeInputField,\n nameInputField,\n emailInputField,\n telInputField\n ].filter(Boolean), (valid) => {\n payButton.disabled = !valid;\n });\n\n validate();\n\n this.show();\n\n let focusField: InputField;\n if(this.focus) {\n const focusMap: {[field in ShippingFocusField]?: InputField} = {\n name: nameInputField,\n email: emailInputField,\n phone: telInputField\n };\n\n focusField = focusMap[this.focus];\n } else {\n focusField = address1InputField;\n }\n\n if(focusField) {\n placeCaretAtEnd(focusField.input);\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '.';\nimport accumulate from '../../helpers/array/accumulate';\nimport paymentsWrapCurrencyAmount from '../../helpers/paymentsWrapCurrencyAmount';\nimport {PaymentsPaymentForm, PaymentsValidatedRequestedInfo, ShippingOption} from '../../layer';\nimport RadioField from '../radioField';\nimport Row, {RadioFormFromRows} from '../row';\nimport SettingSection from '../settingSection';\nimport {PaymentButton} from './payment';\n\nexport default class PopupPaymentShippingMethods extends PopupElement<{\n finish: (shippingOption: ShippingOption) => void\n}> {\n constructor(\n private paymentForm: PaymentsPaymentForm,\n private requestedInfo: PaymentsValidatedRequestedInfo,\n private shippingOption: ShippingOption\n ) {\n super('popup-payment popup-payment-shipping-methods', {\n closable: true,\n overlayClosable: true,\n body: true,\n scrollable: true,\n title: 'PaymentShippingMethod'\n });\n\n this.d();\n }\n\n private d() {\n const section = new SettingSection({name: 'PaymentCheckoutShippingMethod', noDelimiter: true, noShadow: true});\n\n const rows = this.requestedInfo.shipping_options.map((shippingOption) => {\n return new Row({\n radioField: new RadioField({\n text: shippingOption.title,\n name: 'shipping-method',\n value: shippingOption.id\n }),\n subtitle: paymentsWrapCurrencyAmount(\n accumulate(shippingOption.prices.map(({amount}) => +amount), 0),\n this.paymentForm.invoice.currency\n )\n });\n });\n\n let lastShippingId: string;\n const form = RadioFormFromRows(rows, (value) => {\n lastShippingId = value;\n });\n\n if(this.shippingOption) {\n rows.find((row) => row.radioField.input.value === this.shippingOption.id).radioField.checked = true;\n } else {\n rows[0].radioField.checked = true;\n }\n\n section.content.append(form);\n\n this.scrollable.append(section.container);\n\n const payButton = PaymentButton({\n key: 'PaymentInfo.Done',\n onClick: () => {\n this.dispatchEvent('finish', this.requestedInfo.shipping_options.find((option) => option.id === lastShippingId));\n this.hide();\n }\n });\n this.body.append(this.btnConfirmOnEnter = payButton);\n\n this.show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '.';\nimport Currencies from '../../config/currencies';\nimport {FontFamily, FontSize} from '../../config/font';\nimport accumulate from '../../helpers/array/accumulate';\nimport getTextWidth from '../../helpers/canvas/getTextWidth';\nimport {detectUnifiedCardBrand} from '../../helpers/cards/cardBrands';\nimport {attachClickEvent, simulateClickEvent} from '../../helpers/dom/clickEvent';\nimport findUpAsChild from '../../helpers/dom/findUpAsChild';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd';\nimport {renderImageFromUrlPromise} from '../../helpers/dom/renderImageFromUrl';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport toggleDisability from '../../helpers/dom/toggleDisability';\nimport {formatPhoneNumber} from '../../helpers/formatPhoneNumber';\nimport paymentsWrapCurrencyAmount from '../../helpers/paymentsWrapCurrencyAmount';\nimport ScrollSaver from '../../helpers/scrollSaver';\nimport tsNow from '../../helpers/tsNow';\nimport {AccountTmpPassword, InputInvoice, InputPaymentCredentials, LabeledPrice, Message, MessageMedia, PaymentRequestedInfo, PaymentSavedCredentials, PaymentsPaymentForm, PaymentsPaymentReceipt, PaymentsValidatedRequestedInfo, PostAddress, ShippingOption} from '../../layer';\nimport I18n, {i18n, LangPackKey, _i18n} from '../../lib/langPack';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport wrapRichText from '../../lib/richTextProcessor/wrapRichText';\nimport rootScope from '../../lib/rootScope';\nimport AvatarElement from '../avatar';\nimport Button from '../button';\nimport CheckboxField from '../checkboxField';\nimport PeerTitle from '../peerTitle';\nimport {putPreloader} from '../putPreloader';\nimport Row from '../row';\nimport {toastNew} from '../toast';\nimport wrapPeerTitle from '../wrappers/peerTitle';\nimport wrapPhoto from '../wrappers/photo';\nimport PopupPaymentCard, {PaymentCardDetails, PaymentCardDetailsResult} from './paymentCard';\nimport PopupPaymentCardConfirmation from './paymentCardConfirmation';\nimport PopupPaymentShipping, {PaymentShippingAddress} from './paymentShipping';\nimport PopupPaymentShippingMethods from './paymentShippingMethods';\nimport PopupPaymentVerification from './paymentVerification';\n\nconst iconPath = 'assets/img/';\nconst icons = [\n 'amex',\n 'card',\n 'diners',\n 'discover',\n 'jcb',\n 'mastercard',\n 'visa',\n 'unionpay',\n 'mir',\n 'logo'\n];\n\nexport function getPaymentBrandIconPath(brand: string) {\n if(!icons.includes(brand)) {\n return;\n }\n\n return `${iconPath}${brand}.svg`;\n}\n\nexport function PaymentButton(options: {\n onClick: () => Promise<any> | void,\n key?: LangPackKey,\n textEl?: I18n.IntlElement\n}) {\n const textEl = options.textEl ?? new I18n.IntlElement({key: options.key ?? 'PaymentInfo.Done'});\n const key = textEl.key;\n const payButton = Button('btn-primary btn-color-primary payment-item-pay');\n payButton.append(textEl.element);\n attachClickEvent(payButton, async() => {\n const result = options.onClick();\n if(!(result instanceof Promise)) {\n return;\n }\n\n const d = putPreloader(payButton);\n const toggle = toggleDisability([payButton], true);\n textEl.compareAndUpdate({key: 'PleaseWait'});\n try {\n await result;\n } catch(err) {\n if(!(err as any).handled) {\n console.error('payment button error', err);\n }\n\n toggle();\n textEl.compareAndUpdate({key});\n d.remove();\n }\n });\n return payButton;\n}\n\nexport type PaymentsCredentialsToken = {type: 'card', token?: string, id?: string};\n\nexport default class PopupPayment extends PopupElement {\n private tipButtonsMap: Map<number, HTMLElement>;\n\n constructor(\n private message: Message.message,\n private inputInvoice: InputInvoice,\n private paymentForm?: PaymentsPaymentForm | PaymentsPaymentReceipt,\n private isReceipt?: boolean\n ) {\n super('popup-payment', {\n closable: true,\n overlayClosable: true,\n body: true,\n scrollable: true,\n title: true\n });\n\n this.tipButtonsMap = new Map();\n this.d().catch((err) => {\n console.error('payment popup error', err);\n this.hide();\n });\n }\n\n private async d() {\n this.element.classList.add('is-loading');\n this.show();\n\n let confirmed = false;\n const onConfirmed = () => {\n if(confirmed) {\n return;\n }\n\n confirmed = true;\n if(popupPaymentVerification) {\n popupPaymentVerification.hide();\n }\n\n this.hide();\n };\n\n let {paymentForm, message} = this;\n\n if(message) {\n this.listenerSetter.add(rootScope)('payment_sent', ({peerId, mid}) => {\n if(message.peerId === peerId && message.mid === mid) {\n onConfirmed();\n }\n });\n }\n\n const mediaInvoice = message?.media as MessageMedia.messageMediaInvoice;\n const isReceipt = this.isReceipt ??\n (\n mediaInvoice ?\n !!mediaInvoice.receipt_msg_id || mediaInvoice.extended_media?._ === 'messageExtendedMedia' :\n paymentForm._ === 'payments.paymentReceipt'\n );\n const isTest = mediaInvoice ? mediaInvoice.pFlags.test : paymentForm.invoice.pFlags.test;\n\n const photo = mediaInvoice ? mediaInvoice.photo : paymentForm.photo;\n const title = mediaInvoice ? mediaInvoice.title : paymentForm.title;\n const description = mediaInvoice ? mediaInvoice.description : paymentForm.description;\n\n _i18n(this.title, isReceipt ? 'PaymentReceipt' : 'PaymentCheckout');\n if(isTest) {\n this.title.append(' (Test)');\n }\n\n const className = 'payment-item';\n\n const itemEl = document.createElement('div');\n itemEl.classList.add(className);\n\n const detailsClassName = className + '-details';\n const details = document.createElement('div');\n details.classList.add(detailsClassName);\n\n let photoEl: HTMLElement;\n if(photo) {\n photoEl = document.createElement('div');\n photoEl.classList.add(detailsClassName + '-photo', 'media-container-contain');\n wrapPhoto({\n photo: photo,\n container: photoEl,\n boxWidth: 100,\n boxHeight: 100,\n size: {_: 'photoSizeEmpty', type: ''}\n });\n details.append(photoEl);\n }\n\n const linesClassName = detailsClassName + '-lines';\n const linesEl = document.createElement('div');\n linesEl.classList.add(linesClassName);\n\n const titleEl = document.createElement('div');\n titleEl.classList.add(linesClassName + '-title');\n\n const descriptionEl = document.createElement('div');\n descriptionEl.classList.add(linesClassName + '-description');\n\n const botName = document.createElement('div');\n botName.classList.add(linesClassName + '-bot-name');\n\n linesEl.append(titleEl, descriptionEl, botName);\n\n setInnerHTML(titleEl, wrapEmojiText(title));\n setInnerHTML(descriptionEl, wrapEmojiText(description));\n\n const peerTitle = new PeerTitle();\n botName.append(peerTitle.element);\n\n details.append(linesEl);\n itemEl.append(details);\n this.scrollable.append(itemEl);\n\n const preloaderContainer = document.createElement('div');\n preloaderContainer.classList.add(className + '-preloader-container');\n const preloader = putPreloader(preloaderContainer, true);\n this.scrollable.container.append(preloaderContainer);\n\n const inputInvoice = this.inputInvoice;\n if(!paymentForm) {\n if(isReceipt) paymentForm = await this.managers.appPaymentsManager.getPaymentReceipt(message.peerId, mediaInvoice.receipt_msg_id || (inputInvoice as InputInvoice.inputInvoiceMessage).msg_id);\n else paymentForm = await this.managers.appPaymentsManager.getPaymentForm(inputInvoice);\n this.paymentForm = paymentForm;\n }\n\n let savedInfo = (paymentForm as PaymentsPaymentForm).saved_info || (paymentForm as PaymentsPaymentReceipt).info;\n const savedCredentials = (paymentForm as PaymentsPaymentForm).saved_credentials?.[0];\n let [lastRequestedInfo, passwordState, providerPeerTitle] = await Promise.all([\n !isReceipt && savedInfo && this.managers.appPaymentsManager.validateRequestedInfo(inputInvoice, savedInfo),\n savedCredentials && this.managers.passwordManager.getState(),\n wrapPeerTitle({peerId: paymentForm.provider_id.toPeerId()})\n ]);\n\n // console.log(paymentForm, lastRequestedInfo);\n\n await peerTitle.update({peerId: paymentForm.bot_id.toPeerId()});\n preloaderContainer.remove();\n this.element.classList.remove('is-loading');\n\n const wrapAmount = (amount: string | number, skipSymbol?: boolean) => {\n return paymentsWrapCurrencyAmount(amount, currency, skipSymbol);\n };\n\n const {invoice} = paymentForm;\n const currency = invoice.currency;\n\n const isRecurring = invoice.pFlags.recurring && !isReceipt;\n\n await peerTitle.update({peerId: paymentForm.bot_id.toPeerId()});\n const peerTitle2 = isRecurring ? await wrapPeerTitle({peerId: paymentForm.bot_id.toPeerId()}) : undefined;\n preloaderContainer.remove();\n this.element.classList.remove('is-loading');\n\n const makeLabel = () => {\n const labelEl = document.createElement('div');\n labelEl.classList.add(pricesClassName + '-price');\n\n const left = document.createElement('span');\n const right = document.createElement('span');\n labelEl.append(left, right);\n return {label: labelEl, left, right};\n };\n\n const pricesClassName = className + '-prices';\n const prices = document.createElement('div');\n prices.classList.add(pricesClassName);\n const makePricesElements = (prices: LabeledPrice[]) => {\n return prices.map((price) => {\n const {amount, label} = price;\n\n const _label = makeLabel();\n _label.left.textContent = label;\n\n const wrappedAmount = wrapAmount(amount);\n _label.right.textContent = wrappedAmount;\n\n return _label.label;\n });\n };\n\n const pricesElements = makePricesElements(invoice.prices);\n\n let getTipsAmount = (): number => 0;\n let shippingAmount = 0;\n\n const getTotalTotal = () => totalAmount + getTipsAmount() + shippingAmount;\n const setTotal = () => {\n const wrapped = wrapAmount(getTotalTotal());\n totalLabel.right.textContent = wrapped;\n payI18n.compareAndUpdate({\n key: 'PaymentCheckoutPay',\n args: [wrapped]\n });\n };\n\n const payI18n = new I18n.IntlElement();\n\n const totalLabel = makeLabel();\n totalLabel.label.classList.add('is-total');\n _i18n(totalLabel.left, 'PaymentTransactionTotal');\n const totalAmount = accumulate(invoice.prices.map(({amount}) => +amount), 0);\n\n const canTip = (invoice.max_tip_amount !== undefined && !isReceipt) || !!(paymentForm as PaymentsPaymentReceipt).tip_amount;\n if(canTip) {\n const tipsClassName = className + '-tips';\n\n const currencyData = Currencies[currency];\n\n getTipsAmount = () => +getInputValue().replace(/\\D/g, '');\n\n const getInputValue = () => {\n // return input.textContent;\n return input.value;\n };\n\n const setInputWidth = () => {\n const width = getTextWidth(getInputValue(), `500 ${FontSize} ${FontFamily}`);\n input.style.width = width + 'px';\n };\n\n const setInputValue = (amount: string | number) => {\n amount = Math.min(+amount, +invoice.max_tip_amount);\n const wrapped = wrapAmount(amount, true);\n\n input.value = wrapped;\n // input.textContent = wrapped;\n if(document.activeElement === input) {\n placeCaretAtEnd(input);\n }\n\n unsetActiveTip && unsetActiveTip();\n const tipEl = this.tipButtonsMap.get(amount);\n if(tipEl) {\n tipEl.classList.add('active');\n }\n\n setInputWidth();\n setTotal();\n };\n\n const tipsLabel = makeLabel();\n _i18n(tipsLabel.left, isReceipt ? 'PaymentTip' : 'PaymentTipOptional');\n const input = document.createElement('input');\n input.type = 'tel';\n // const input: HTMLElement = document.createElement('div');\n // input.contentEditable = 'true';\n input.classList.add('input-clear', tipsClassName + '-input');\n tipsLabel.right.append(input);\n\n if(!isReceipt) {\n tipsLabel.label.style.cursor = 'text';\n } else {\n tipsLabel.label.classList.add('disable-hover');\n }\n\n tipsLabel.label.addEventListener('mousedown', (e) => {\n if(!findUpAsChild(e.target as HTMLElement, input)) {\n placeCaretAtEnd(input);\n }\n });\n\n const haveToIgnoreEvents = input instanceof HTMLInputElement ? 1 : 2;\n const onSelectionChange = () => {\n if(ignoreNextSelectionChange) {\n --ignoreNextSelectionChange;\n return;\n }\n\n // setTimeout(() => {\n ignoreNextSelectionChange = haveToIgnoreEvents;\n placeCaretAtEnd(input);\n // }, 0);\n };\n\n const onFocus = () => {\n // cancelEvent(e);\n setTimeout(() => {\n ignoreNextSelectionChange = haveToIgnoreEvents;\n placeCaretAtEnd(input);\n document.addEventListener('selectionchange', onSelectionChange);\n }, 0);\n };\n\n const onFocusOut = () => {\n input.addEventListener('focus', onFocus, {once: true});\n document.removeEventListener('selectionchange', onSelectionChange);\n };\n\n let ignoreNextSelectionChange: number;\n input.addEventListener('focusout', onFocusOut);\n onFocusOut();\n\n input.addEventListener('input', () => {\n setInputValue(getTipsAmount());\n });\n\n const s = [currencyData.symbol, currencyData.space_between ? ' ' : ''];\n if(!currencyData.symbol_left) s.reverse();\n tipsLabel.right[currencyData.symbol_left ? 'prepend' : 'append'](s.join(''));\n\n pricesElements.push(tipsLabel.label);\n\n //\n let unsetActiveTip: () => void;\n if(!isReceipt) {\n const tipsEl = document.createElement('div');\n tipsEl.classList.add(tipsClassName);\n\n const tipClassName = tipsClassName + '-tip';\n const tipButtons = invoice.suggested_tip_amounts.map((tipAmount) => {\n const button = Button(tipClassName, {noRipple: true});\n button.textContent = wrapAmount(tipAmount);\n\n this.tipButtonsMap.set(+tipAmount, button);\n return button;\n });\n\n unsetActiveTip = () => {\n const prevTipEl = tipsEl.querySelector('.active');\n if(prevTipEl) {\n prevTipEl.classList.remove('active');\n }\n };\n\n attachClickEvent(tipsEl, (e) => {\n const tipEl = findUpClassName(e.target, tipClassName);\n if(!tipEl) {\n return;\n }\n\n let tipAmount = 0;\n if(tipEl.classList.contains('active')) {\n tipEl.classList.remove('active');\n } else {\n unsetActiveTip();\n tipEl.classList.add('active');\n\n for(const [amount, el] of this.tipButtonsMap) {\n if(el === tipEl) {\n tipAmount = amount;\n break;\n }\n }\n }\n\n setInputValue(tipAmount);\n });\n\n setInputValue(0);\n\n tipsEl.append(...tipButtons);\n pricesElements.push(tipsEl);\n } else {\n setInputValue((paymentForm as PaymentsPaymentReceipt).tip_amount);\n }\n } else {\n setTotal();\n }\n\n pricesElements.push(totalLabel.label);\n\n prices.append(...pricesElements);\n itemEl.append(prices);\n\n // /\n\n const setRowIcon = async(row: Row, icon?: string) => {\n const img = document.createElement('img');\n img.classList.add('media-photo');\n await renderImageFromUrlPromise(img, getPaymentBrandIconPath(icon));\n let container = row.media;\n if(!container) {\n container = row.createMedia('small');\n container.classList.add('media-container-cover');\n container.append(img);\n } else {\n replaceContent(container, img);\n }\n\n row.container.classList.remove('row-with-icon');\n };\n\n const createRow = (options: ConstructorParameters<typeof Row>[0]) => {\n if(options.titleLangKey) {\n options.subtitleLangKey = options.titleLangKey;\n }\n\n options.noWrap = true;\n const row = new Row(options);\n row.container.classList.add(className + '-row');\n\n if(options.titleLangKey) {\n row.subtitle.classList.add('hide');\n }\n\n return row;\n };\n\n const setRowTitle = (row: Row, textContent: string) => {\n row.title.textContent = textContent;\n if(!textContent) {\n const e = I18n.weakMap.get(row.subtitle.firstElementChild as HTMLElement) as I18n.IntlElement;\n row.title.append(i18n(e.key));\n }\n\n row.subtitle.classList.toggle('hide', !textContent);\n };\n\n const setCardSubtitle = (card: PaymentCardDetailsResult) => {\n let brand: string;\n let str: string;\n let icon: string;\n if('title' in card) {\n brand = card.title.split(' ').shift();\n str = card.title;\n icon = card.icon;\n } else {\n brand = detectUnifiedCardBrand(card.cardNumber);\n str = brand + ' *' + card.cardNumber.split(' ').pop();\n }\n\n methodRow.title.classList.remove('tgico', 'tgico-card_outline');\n setRowIcon(methodRow, icon || brand.toLowerCase());\n setRowTitle(methodRow, str);\n };\n\n const onMethodClick = () => {\n PopupElement.createPopup(PopupPaymentCard, paymentForm as PaymentsPaymentForm, previousCardDetails as PaymentCardDetails).addEventListener('finish', ({token, card}) => {\n previousToken = token, previousCardDetails = card;\n\n setCardSubtitle(card);\n });\n };\n\n let previousCardDetails: PaymentCardDetailsResult, previousToken: PaymentsCredentialsToken;\n const methodRow = createRow({\n titleLangKey: 'PaymentCheckoutMethod',\n clickable: isReceipt ? undefined : onMethodClick,\n icon: 'card_outline'\n });\n\n methodRow.container.classList.add(className + '-method-row');\n\n if(savedCredentials) {\n setCardSubtitle(savedCredentials);\n } else if((paymentForm as PaymentsPaymentReceipt).credentials_title) {\n setCardSubtitle({title: (paymentForm as PaymentsPaymentReceipt).credentials_title});\n }\n\n const providerRow = createRow({\n title: providerPeerTitle,\n subtitleLangKey: 'PaymentCheckoutProvider'\n });\n\n const providerAvatar = new AvatarElement();\n providerAvatar.classList.add('avatar-32');\n providerRow.createMedia('small').append(providerAvatar);\n /* await */ providerAvatar.updateWithOptions({peerId: paymentForm.provider_id.toPeerId()});\n\n let shippingAddressRow: Row, shippingNameRow: Row, shippingEmailRow: Row, shippingPhoneRow: Row, shippingMethodRow: Row;\n let lastShippingOption: ShippingOption, onShippingAddressClick: (focus?: ConstructorParameters<typeof PopupPaymentShipping>[2]) => void, onShippingMethodClick: () => void;\n const setShippingTitle = invoice.pFlags.shipping_address_requested ? (shippingAddress?: PaymentShippingAddress) => {\n if(!shippingAddress) {\n shippingMethodRow.subtitle.classList.add('hide');\n replaceContent(shippingMethodRow.title, i18n('PaymentShippingAddress'));\n return;\n }\n\n const postAddress = shippingAddress.shipping_address;\n setRowTitle(shippingAddressRow, [postAddress.city, postAddress.street_line1, postAddress.street_line2].filter(Boolean).join(', '));\n\n shippingMethodRow.container.classList.toggle('hide', !lastRequestedInfo && !isReceipt);\n } : undefined;\n\n const setShippingInfo = (info: PaymentRequestedInfo) => {\n setShippingTitle && setShippingTitle(info);\n shippingNameRow && setRowTitle(shippingNameRow, info.name);\n shippingEmailRow && setRowTitle(shippingEmailRow, info.email);\n shippingPhoneRow && setRowTitle(shippingPhoneRow, info.phone && ('+' + formatPhoneNumber(info.phone).formatted));\n };\n\n if(!isReceipt) {\n onShippingAddressClick = (focus) => {\n PopupElement.createPopup(PopupPaymentShipping, paymentForm as PaymentsPaymentForm, inputInvoice, focus).addEventListener('finish', ({shippingAddress, requestedInfo}) => {\n lastRequestedInfo = requestedInfo;\n savedInfo = (paymentForm as PaymentsPaymentForm).saved_info = shippingAddress;\n setShippingInfo(shippingAddress);\n });\n };\n }\n\n if(invoice.pFlags.shipping_address_requested) {\n const setShippingOption = (shippingOption?: ShippingOption) => {\n const scrollSaver = new ScrollSaver(this.scrollable, undefined, true);\n scrollSaver.save();\n if(lastShippingPricesElements) {\n lastShippingPricesElements.forEach((node) => node.remove());\n }\n\n if(!shippingOption) {\n shippingAmount = 0;\n\n setTotal();\n scrollSaver.restore();\n this.onContentUpdate();\n return;\n }\n\n lastShippingOption = shippingOption;\n setRowTitle(shippingMethodRow, shippingOption.title);\n\n shippingAmount = accumulate(shippingOption.prices.map(({amount}) => +amount), 0);\n lastShippingPricesElements = makePricesElements(shippingOption.prices);\n let l = totalLabel.label;\n if(canTip) {\n l = l.previousElementSibling as any;\n if(!isReceipt) {\n l = l.previousElementSibling as any;\n }\n }\n\n lastShippingPricesElements.forEach((element) => l.parentElement.insertBefore(element, l));\n\n setTotal();\n scrollSaver.restore();\n this.onContentUpdate();\n };\n\n shippingAddressRow = createRow({\n icon: 'location',\n titleLangKey: 'PaymentShippingAddress',\n clickable: !isReceipt && onShippingAddressClick.bind(null, undefined)\n });\n\n let lastShippingPricesElements: HTMLElement[];\n shippingMethodRow = createRow({\n icon: 'shipping',\n titleLangKey: 'PaymentCheckoutShippingMethod',\n clickable: !isReceipt && (onShippingMethodClick = () => {\n PopupElement.createPopup(PopupPaymentShippingMethods, paymentForm as PaymentsPaymentForm, lastRequestedInfo, lastShippingOption).addEventListener('finish', (shippingOption) => {\n setShippingOption(shippingOption);\n });\n })\n });\n\n shippingMethodRow.container.classList.add('hide');\n\n const shippingOption = (paymentForm as PaymentsPaymentReceipt).shipping;\n if(shippingOption) {\n setShippingOption(shippingOption);\n }\n }\n\n if(invoice.pFlags.name_requested) {\n shippingNameRow = createRow({\n icon: 'newprivate',\n titleLangKey: 'PaymentCheckoutName',\n clickable: !isReceipt && onShippingAddressClick.bind(null, 'name')\n });\n }\n\n if(invoice.pFlags.email_requested) {\n shippingEmailRow = createRow({\n icon: 'mention',\n titleLangKey: 'PaymentShippingEmailPlaceholder',\n clickable: !isReceipt && onShippingAddressClick.bind(null, 'email')\n });\n }\n\n if(invoice.pFlags.phone_requested) {\n shippingPhoneRow = createRow({\n icon: 'phone',\n titleLangKey: 'PaymentCheckoutPhoneNumber',\n clickable: !isReceipt && onShippingAddressClick.bind(null, 'phone')\n });\n }\n\n if(savedInfo) {\n setShippingInfo(savedInfo);\n }\n\n const rows = [\n methodRow,\n providerRow,\n shippingAddressRow,\n shippingMethodRow,\n shippingNameRow,\n shippingEmailRow,\n shippingPhoneRow\n ].filter(Boolean);\n\n const acceptTermsCheckboxField = isRecurring && new CheckboxField({\n text: 'Payments.Recurrent.Accept',\n textArgs: [wrapRichText(invoice.recurring_terms_url), peerTitle2]\n });\n\n const acceptTermsRow = isRecurring && createRow({\n checkboxField: acceptTermsCheckboxField\n });\n\n const recurringElements = isRecurring ? [document.createElement('hr'), acceptTermsRow.container] : [];\n\n this.scrollable.append(...[\n document.createElement('hr'),\n ...rows.map((row) => row.container),\n ...recurringElements\n ].filter(Boolean));\n\n // /\n let popupPaymentVerification: PopupPaymentVerification, lastTmpPasword: AccountTmpPassword;\n const onClick = () => {\n const missingInfo = invoice.pFlags.name_requested && !savedInfo?.name ? 'name' : (invoice.pFlags.email_requested && !savedInfo?.email ? 'email' : (invoice.pFlags.phone_requested && !savedInfo?.phone ? 'phone' : undefined));\n if(invoice.pFlags.shipping_address_requested) {\n if(!lastRequestedInfo) {\n onShippingAddressClick();\n return;\n } else if(!lastShippingOption) {\n onShippingMethodClick();\n return;\n }\n } else if(missingInfo) {\n onShippingAddressClick(missingInfo);\n return;\n }\n\n if(!previousCardDetails && !lastTmpPasword) {\n if(!savedCredentials) {\n onMethodClick();\n return;\n }\n\n Promise.resolve(passwordState ?? this.managers.passwordManager.getState()).then((_passwordState) => {\n PopupElement.createPopup(PopupPaymentCardConfirmation, savedCredentials.title, _passwordState).addEventListener('finish', (tmpPassword) => {\n passwordState = undefined;\n lastTmpPasword = tmpPassword;\n simulateClickEvent(payButton);\n\n // * reserve 5 seconds\n const diff = tmpPassword.valid_until - tsNow(true) - 5;\n setTimeout(() => {\n if(lastTmpPasword === tmpPassword) {\n lastTmpPasword = undefined;\n }\n }, diff * 1000);\n });\n });\n\n return;\n }\n\n return Promise.resolve().then(async() => {\n const credentials: InputPaymentCredentials = lastTmpPasword ? {\n _: 'inputPaymentCredentialsSaved',\n id: savedCredentials.id,\n tmp_password: lastTmpPasword.tmp_password\n } : {\n _: 'inputPaymentCredentials',\n data: {\n _: 'dataJSON',\n data: JSON.stringify(previousToken.token ? previousToken : {type: previousToken.type, id: previousToken.id})\n },\n pFlags: {\n save: previousCardDetails.save || undefined\n }\n };\n\n try {\n const paymentResult = await this.managers.appPaymentsManager.sendPaymentForm(\n inputInvoice,\n (paymentForm as PaymentsPaymentForm).form_id,\n lastRequestedInfo?.id,\n lastShippingOption?.id,\n credentials,\n getTipsAmount()\n );\n\n if(paymentResult._ === 'payments.paymentResult') {\n onConfirmed();\n } else {\n popupPaymentVerification = PopupElement.createPopup(PopupPaymentVerification, paymentResult.url, !mediaInvoice.extended_media);\n popupPaymentVerification.addEventListener('finish', () => {\n popupPaymentVerification = undefined;\n\n onConfirmed();\n });\n await new Promise<void>((resolve, reject) => {\n popupPaymentVerification.addEventListener('close', () => {\n popupPaymentVerification = undefined;\n if(confirmed) {\n resolve();\n } else {\n const err = new Error('payment not finished');\n (err as ApiError).handled = true;\n reject(err);\n }\n });\n });\n }\n } catch(err) {\n if((err as ApiError).type === 'BOT_PRECHECKOUT_TIMEOUT') {\n toastNew({langPackKey: 'Error.AnError'});\n (err as ApiError).handled = true;\n } else if((err as ApiError).type === 'TMP_PASSWORD_INVALID') {\n passwordState = lastTmpPasword = undefined;\n simulateClickEvent(payButton);\n (err as ApiError).handled = true;\n }\n\n throw err;\n }\n });\n };\n\n const onChange = () => {\n payButton.disabled = !!(acceptTermsCheckboxField && !acceptTermsCheckboxField.checked);\n };\n\n let payButton: HTMLButtonElement;\n if(isReceipt) {\n payButton = PaymentButton({\n onClick: () => this.hide(),\n key: 'Done'\n });\n } else {\n payButton = PaymentButton({\n onClick: onClick,\n textEl: payI18n\n });\n }\n\n onChange();\n if(acceptTermsCheckboxField) {\n acceptTermsCheckboxField.input.addEventListener('change', onChange);\n }\n\n this.body.append(this.btnConfirmOnEnter = payButton);\n\n this.onContentUpdate();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport AvatarElement from '../avatar';\nimport PopupElement, {addCancelButton, PopupButton, PopupOptions} from '.';\nimport {i18n, LangPackKey} from '../../lib/langPack';\nimport CheckboxField, {CheckboxFieldOptions} from '../checkboxField';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\n\nexport type PopupPeerButton = Omit<PopupButton, 'callback'> & Partial<{callback: PopupPeerButtonCallback}>;\nexport type PopupPeerButtonCallbackCheckboxes = Set<LangPackKey>;\nexport type PopupPeerButtonCallback = (checkboxes?: PopupPeerButtonCallbackCheckboxes) => void;\nexport type PopupPeerCheckboxOptions = CheckboxFieldOptions & {checkboxField?: CheckboxField};\n\nexport type PopupPeerOptions = Omit<PopupOptions, 'buttons' | 'title'> & Partial<{\n peerId: PeerId,\n threadId: number,\n title: string | HTMLElement,\n titleLangKey: LangPackKey,\n titleLangArgs: any[],\n noTitle: boolean,\n description: Parameters<typeof setInnerHTML>[1],\n descriptionLangKey: LangPackKey,\n descriptionLangArgs: any[],\n buttons: Array<PopupPeerButton>,\n checkboxes: Array<PopupPeerCheckboxOptions>\n}>;\nexport default class PopupPeer extends PopupElement {\n protected description: HTMLParagraphElement;\n\n constructor(private className: string, options: PopupPeerOptions = {}) {\n super('popup-peer' + (className ? ' ' + className : ''), {\n overlayClosable: true,\n ...options,\n title: true,\n buttons: options.buttons && addCancelButton(options.buttons)\n });\n\n if(options.peerId) {\n const avatarEl = new AvatarElement();\n avatarEl.classList.add('avatar-32');\n avatarEl.updateWithOptions({\n isDialog: true,\n peerId: options.peerId,\n threadId: options.threadId,\n wrapOptions: {\n middleware: this.middlewareHelper.get()\n }\n });\n this.header.prepend(avatarEl);\n }\n\n if(!options.noTitle) {\n if(options.titleLangKey || !options.title) this.title.append(i18n(options.titleLangKey || 'AppName', options.titleLangArgs));\n else if(options.title instanceof HTMLElement) {\n this.title.append(options.title);\n } else this.title.innerText = options.title || '';\n }\n\n const fragment = document.createDocumentFragment();\n\n if(options.descriptionLangKey || options.description) {\n const p = this.description = document.createElement('p');\n p.classList.add('popup-description');\n if(options.descriptionLangKey) p.append(i18n(options.descriptionLangKey, options.descriptionLangArgs));\n else if(options.description) setInnerHTML(p, options.description);\n\n fragment.append(p);\n }\n\n if(options.checkboxes) {\n this.container.classList.add('have-checkbox');\n\n options.checkboxes.forEach((o) => {\n o.withRipple = true;\n const checkboxField = new CheckboxField(o);\n o.checkboxField = checkboxField;\n fragment.append(checkboxField.label);\n });\n\n options.buttons.forEach((button) => {\n if(button.callback) {\n const original = button.callback;\n button.callback = () => {\n const c: Set<LangPackKey> = new Set();\n options.checkboxes.forEach((o) => {\n if(o.checkboxField.checked) {\n c.add(o.text);\n }\n });\n original(c);\n };\n }\n });\n }\n\n this.container.insertBefore(fragment, this.header.nextElementSibling);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport AppSelectPeers from '../appSelectPeers';\nimport PopupElement from '.';\nimport {LangPackKey, _i18n} from '../../lib/langPack';\n\nexport default class PopupPickUser extends PopupElement {\n protected selector: AppSelectPeers;\n\n constructor(options: {\n peerTypes: AppSelectPeers['peerType'],\n onSelect?: (peerId: PeerId) => Promise<void> | void,\n placeholder: LangPackKey,\n chatRightsActions?: AppSelectPeers['chatRightsActions'],\n peerId?: number,\n selfPresence?: LangPackKey\n }) {\n super('popup-forward', {closable: true, overlayClosable: true, body: true, title: true});\n\n this.selector = new AppSelectPeers({\n appendTo: this.body,\n onChange: async() => {\n const selected = this.selector.getSelected();\n const peerId = selected[selected.length - 1].toPeerId();\n\n if(options.onSelect) {\n const res = options.onSelect(peerId);\n if(res instanceof Promise) {\n try {\n await res;\n } catch(err) {\n return;\n }\n }\n }\n\n this.selector = null;\n this.hide();\n },\n peerType: options.peerTypes,\n onFirstRender: () => {\n this.show();\n this.selector.checkForTriggers(); // ! due to zero height before mounting\n\n if(!IS_TOUCH_SUPPORTED) {\n this.selector.input.focus();\n }\n },\n chatRightsActions: options.chatRightsActions,\n multiSelect: false,\n rippleEnabled: false,\n avatarSize: 'abitbigger',\n peerId: options.peerId,\n placeholder: options.placeholder,\n selfPresence: options.selfPresence,\n managers: this.managers\n });\n\n this.scrollable = this.selector.scrollable;\n this.attachScrollableListeners();\n\n // this.scrollable = new Scrollable(this.body);\n\n this.title.append(this.selector.input);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupPeer from './peer';\n\nexport default class PopupSendNow extends PopupPeer {\n constructor(peerId: PeerId, mids: number[], onConfirm?: () => void) {\n super('popup-delete-chat', {\n title: `Send Message${mids.length > 1 ? 's' : ''} Now`,\n description: mids.length > 1 ? 'Send ' + mids.length + ' messages now?' : 'Send message now?',\n buttons: [{\n langKey: 'Send',\n callback: () => {\n onConfirm && onConfirm();\n this.managers.appMessagesManager.sendScheduledMessages(peerId, mids);\n }\n }]\n });\n\n this.show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {AppStickersManager} from '../../lib/appManagers/appStickersManager';\nimport PopupElement from '.';\nimport wrapSticker from '../wrappers/sticker';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport {putPreloader} from '../putPreloader';\nimport animationIntersector, {AnimationItemGroup} from '../animationIntersector';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport {i18n} from '../../lib/langPack';\nimport Button from '../button';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport toggleDisability from '../../helpers/dom/toggleDisability';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport {toastNew} from '../toast';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport createStickersContextMenu from '../../helpers/dom/createStickersContextMenu';\nimport attachStickerViewerListeners from '../stickerViewer';\nimport {Document, StickerSet} from '../../layer';\nimport Row from '../row';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport rootScope from '../../lib/rootScope';\nimport wrapCustomEmoji from '../wrappers/customEmoji';\nimport emoticonsDropdown from '../emoticonsDropdown';\nimport ButtonMenuToggle from '../buttonMenuToggle';\nimport {copyTextToClipboard} from '../../helpers/clipboard';\n\nconst ANIMATION_GROUP: AnimationItemGroup = 'STICKERS-POPUP';\n\nexport default class PopupStickers extends PopupElement {\n private stickersFooter: HTMLElement;\n private appendTo: HTMLElement;\n private updateAdded: {[setId: Long]: (added: boolean) => void};\n private sets: StickerSet.stickerSet[];\n private button: HTMLElement;\n\n constructor(\n private stickerSetInput: Parameters<AppStickersManager['getStickerSet']>[0] | Parameters<AppStickersManager['getStickerSet']>[0][],\n private isEmojis?: boolean\n ) {\n super('popup-stickers', {closable: true, overlayClosable: true, body: true, scrollable: true, title: true});\n\n this.title.append(i18n('Loading'));\n this.updateAdded = {};\n\n emoticonsDropdown.setIgnoreMouseOut('popup', true);\n this.addEventListener('close', () => {\n emoticonsDropdown.setIgnoreMouseOut('popup', false);\n animationIntersector.setOnlyOnePlayableGroup();\n });\n\n this.appendTo = this.scrollable.container;\n\n this.appendTo.classList.add('is-loading');\n putPreloader(this.appendTo, true);\n\n this.stickersFooter = document.createElement('div');\n this.stickersFooter.classList.add('sticker-set-footer');\n\n const btn = Button('btn-primary btn-primary-transparent disable-hover', {noRipple: true, text: 'Loading'});\n this.stickersFooter.append(btn);\n\n this.body.append(this.stickersFooter);\n\n attachStickerViewerListeners({listenTo: this.appendTo, listenerSetter: this.listenerSetter});\n\n const onStickerSetUpdate = (set: StickerSet.stickerSet) => {\n const idx = this.sets.findIndex((_set) => _set.id === set.id);\n if(idx === -1) {\n return;\n }\n\n this.sets[idx] = set;\n const updateAdded = this.updateAdded[set.id];\n updateAdded?.(!!set.installed_date);\n this.updateButton();\n };\n\n this.listenerSetter.add(rootScope)('stickers_installed', onStickerSetUpdate);\n this.listenerSetter.add(rootScope)('stickers_deleted', onStickerSetUpdate);\n\n this.loadStickerSet();\n }\n\n private createStickerSetElements(set?: StickerSet.stickerSet) {\n const container = document.createElement('div');\n container.classList.add('sticker-set');\n\n let headerRow: Row, updateAdded: (added: boolean) => void;\n if(set) {\n headerRow = new Row({\n title: wrapEmojiText(set.title),\n subtitle: i18n(set.pFlags.emojis ? 'EmojiCount' : 'Stickers', [set.count]),\n buttonRight: true\n });\n\n updateAdded = (added) => {\n replaceContent(headerRow.buttonRight, i18n(added ? 'Stickers.SearchAdded' : 'Stickers.SearchAdd'));\n headerRow.buttonRight.classList.toggle('active', added);\n };\n\n updateAdded(!!set.installed_date);\n\n container.append(headerRow.container);\n }\n\n const itemsContainer = document.createElement('div');\n itemsContainer.classList.add('sticker-set-stickers');\n\n container.append(itemsContainer);\n\n return {container, headerRow, updateAdded, itemsContainer};\n }\n\n private onStickersClick = async(e: MouseEvent) => {\n const target = findUpClassName(e.target, 'sticker-set-sticker');\n if(!target) return;\n\n const docId = target.dataset.docId;\n if(await appImManager.chat.input.sendMessageWithDocument(docId)) {\n this.hide();\n }\n };\n\n private async loadStickerSet() {\n const middleware = this.middlewareHelper.get();\n const inputs = Array.isArray(this.stickerSetInput) ? this.stickerSetInput : [this.stickerSetInput];\n const setsPromises = inputs.map((input) => this.managers.appStickersManager.getStickerSet(input));\n let sets = await Promise.all(setsPromises);\n if(!middleware()) return;\n let firstSet = sets[0];\n if(sets.length === 1 && !firstSet) {\n toastNew({langPackKey: this.isEmojis ? 'AddEmojiNotFound' : 'StickerSet.DontExist'});\n this.hide();\n return;\n }\n\n sets = sets.filter(Boolean);\n firstSet = sets[0];\n\n this.sets = sets.map((set) => set.set);\n\n const isEmojis = this.isEmojis ??= !!firstSet.set.pFlags.emojis;\n\n if(!isEmojis) {\n attachClickEvent(this.appendTo, this.onStickersClick, {listenerSetter: this.listenerSetter});\n\n const {destroy} = createStickersContextMenu({\n listenTo: this.appendTo,\n isStickerPack: true,\n onSend: () => this.hide()\n });\n\n this.addEventListener('close', destroy);\n }\n\n animationIntersector.setOnlyOnePlayableGroup(ANIMATION_GROUP);\n\n const lazyLoadQueue = new LazyLoadQueue();\n const loadPromises: Promise<any>[] = [];\n\n const containersPromises = sets.map(async(set) => {\n const {container, itemsContainer, headerRow, updateAdded} = this.createStickerSetElements(sets.length > 1 ? set.set : undefined);\n\n if(headerRow) {\n attachClickEvent(headerRow.buttonRight, () => {\n this.managers.appStickersManager.toggleStickerSet(set.set);\n }, {listenerSetter: this.listenerSetter});\n }\n\n this.updateAdded[set.set.id] = updateAdded;\n\n let divs: (HTMLElement | DocumentFragment)[];\n\n const docs = set.documents.filter((doc) => doc?._ === 'document') as Document.document[];\n if(isEmojis) {\n const fragment = wrapCustomEmoji({\n docIds: docs.map((doc) => doc.id),\n loadPromises,\n animationGroup: ANIMATION_GROUP,\n customEmojiSize: mediaSizes.active.esgCustomEmoji,\n middleware\n // lazyLoadQueue\n });\n\n (Array.from(fragment.children) as HTMLElement[]).slice(1).forEach((element) => {\n const span = document.createElement('span');\n span.classList.add('super-emoji');\n element.replaceWith(span);\n span.append(element);\n });\n\n divs = [fragment];\n\n itemsContainer.classList.replace('sticker-set-stickers', 'super-emojis');\n itemsContainer.classList.add('is-emojis', 'not-local');\n } else {\n divs = await Promise.all(docs.map(async(doc) => {\n const div = document.createElement('div');\n div.classList.add('sticker-set-sticker');\n\n const size = mediaSizes.active.popupSticker.width;\n\n await wrapSticker({\n doc,\n div,\n lazyLoadQueue,\n group: ANIMATION_GROUP,\n play: true,\n loop: true,\n width: size,\n height: size,\n withLock: true,\n loadPromises,\n middleware\n });\n\n return div;\n }));\n }\n\n itemsContainer.append(...divs.filter(Boolean));\n\n return container;\n });\n\n const containers = await Promise.all(containersPromises);\n await Promise.all(loadPromises);\n\n const button = this.button = Button('', {noRipple: true});\n\n this.updateButton();\n\n attachClickEvent(button, () => {\n const toggle = toggleDisability([button], true);\n\n this.managers.appStickersManager.toggleStickerSets(sets.map((set) => set.set)).then(() => {\n this.hide();\n }).catch(() => {\n toggle();\n });\n }, {listenerSetter: this.listenerSetter});\n\n if(sets.length === 1) {\n setInnerHTML(this.title, wrapEmojiText(firstSet.set.title));\n } else {\n setInnerHTML(this.title, i18n('Emoji'));\n }\n\n const btnMenu = ButtonMenuToggle({\n listenerSetter: this.listenerSetter,\n buttons: [{\n icon: 'copy',\n text: 'CopyLink',\n onClick: () => {\n const prefix = `https://t.me/${this.isEmojis ? 'addemoji' : 'addstickers'}/`;\n const text = sets.map((set) => prefix + set.set.short_name).join('\\n');\n copyTextToClipboard(text);\n }\n }],\n direction: 'bottom-left'\n });\n this.title.after(btnMenu);\n\n this.stickersFooter.textContent = '';\n this.stickersFooter.append(button);\n\n this.appendTo.classList.remove('is-loading');\n this.appendTo.textContent = '';\n this.appendTo.append(...containers);\n\n this.scrollable.onAdditionalScroll();\n }\n\n private updateButton() {\n const {sets, isEmojis} = this;\n let isAdd: boolean, buttonAppend: HTMLElement;\n if(sets.length === 1) {\n const firstSet = sets[0];\n buttonAppend = i18n(isEmojis ? 'EmojiCount' : 'Stickers', [firstSet.count]);\n isAdd = !firstSet.installed_date;\n } else {\n const installed = sets.filter((set) => set.installed_date);\n let count: number;\n if(sets.length === installed.length) {\n isAdd = false;\n count = sets.length;\n } else {\n isAdd = true;\n count = sets.length - installed.length;\n }\n\n buttonAppend = i18n('EmojiPackCount', [count]);\n }\n\n this.button.className = isAdd ? 'btn-primary btn-color-primary' : 'btn-primary btn-primary-transparent danger';\n replaceContent(this.button, i18n(isAdd ? 'AddStickersCount' : 'RemoveStickersCount', [buttonAppend]));\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement, {addCancelButton} from '.';\nimport PopupPeer, {PopupPeerButtonCallbackCheckboxes, PopupPeerOptions} from './peer';\nimport rootScope from '../../lib/rootScope';\nimport {FormatterArguments, LangPackKey} from '../../lib/langPack';\nimport wrapPeerTitle from '../wrappers/peerTitle';\n\nexport default class PopupPinMessage {\n constructor(private peerId: PeerId, private mid: number, private unpin?: true, private onConfirm?: () => void) {\n this.construct();\n }\n\n private async construct() {\n const {peerId, mid, unpin, onConfirm} = this;\n let title: LangPackKey, description: LangPackKey, descriptionArgs: FormatterArguments;\n const buttons: PopupPeerOptions['buttons'] = [], checkboxes: PopupPeerOptions['checkboxes'] = [];\n\n const managers = PopupElement.MANAGERS;\n\n const canUnpin = await managers.appPeersManager.canPinMessage(peerId);\n\n const callback = (checked: PopupPeerButtonCallbackCheckboxes, oneSide?: boolean, silent?: boolean) => {\n setTimeout(() => { // * костыль, потому что document.elementFromPoint вернёт popup-peer пока он будет закрываться\n let promise: Promise<any>;\n if(unpin && !mid) {\n if(canUnpin) {\n promise = managers.appMessagesManager.unpinAllMessages(peerId);\n } else {\n promise = managers.appMessagesManager.hidePinnedMessages(peerId);\n }\n } else {\n promise = managers.appMessagesManager.updatePinnedMessage(peerId, mid, unpin, silent, oneSide);\n }\n\n if(onConfirm) {\n promise.then(onConfirm);\n }\n }, 300);\n };\n\n if(unpin) {\n let buttonText: LangPackKey = 'UnpinMessage';\n if(!mid) {\n if(canUnpin) {\n title = 'Popup.Unpin.AllTitle';\n description = 'Chat.UnpinAllMessagesConfirmation';\n descriptionArgs = ['' + ((await managers.appMessagesManager.getPinnedMessagesCount(peerId)) || 1)];\n } else {\n title = 'Popup.Unpin.HideTitle';\n description = 'Popup.Unpin.HideDescription';\n buttonText = 'Popup.Unpin.Hide';\n }\n } else {\n title = 'UnpinMessageAlertTitle';\n description = 'Chat.Confirm.Unpin';\n }\n\n buttons.push({\n langKey: buttonText,\n isDanger: true,\n callback\n });\n } else {\n title = 'PinMessageAlertTitle';\n const pinButtonText: LangPackKey = 'PinMessage';\n\n if(peerId.isAnyChat()) {\n buttons.push({\n langKey: pinButtonText,\n callback: (checked) => callback(checked, false, !checked.size)\n });\n\n if(await managers.appChatsManager.isBroadcast(peerId.toChatId())) {\n description = 'PinMessageAlertChannel';\n } else {\n description = 'PinMessageAlert';\n\n checkboxes.push({\n text: 'PinNotify',\n checked: true\n });\n }\n } else {\n description = 'PinMessageAlertChat';\n\n if(peerId === rootScope.myId) {\n buttons.push({\n langKey: pinButtonText,\n callback\n });\n } else {\n buttons.push({\n langKey: pinButtonText,\n callback: (checked) => callback(checked, !checked.size)\n });\n\n checkboxes.push({\n text: 'PinAlsoFor',\n textArgs: [await wrapPeerTitle({peerId})],\n checked: true\n });\n }\n }\n }\n\n addCancelButton(buttons);\n\n const popup = PopupElement.createPopup(PopupPeer, 'popup-delete-chat', {\n peerId,\n titleLangKey: title,\n descriptionLangKey: description,\n descriptionLangArgs: descriptionArgs,\n buttons,\n checkboxes\n });\n\n popup.show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {CancellablePromise} from '../helpers/cancellablePromise';\nimport SetTransition from './singleTransition';\nimport {fastRaf} from '../helpers/schedulers';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport isInDOM from '../helpers/dom/isInDOM';\nimport safeAssign from '../helpers/object/safeAssign';\n\nconst TRANSITION_TIME = 200;\n\nexport default class ProgressivePreloader {\n public preloader: HTMLDivElement;\n public circle: SVGCircleElement;\n private cancelSvg: SVGSVGElement;\n private downloadSvg: HTMLElement;\n\n private tempId = 0;\n public detached = true;\n\n public promise: CancellablePromise<any> = null;\n\n public isUpload = false;\n private cancelable = true;\n private streamable = false;\n private tryAgainOnFail = true;\n private attachMethod: 'append' | 'prepend' = 'append';\n\n public loadFunc: (e?: Event) => any;\n\n public totalLength: number;\n\n constructor(options?: Partial<{\n isUpload: ProgressivePreloader['isUpload'],\n cancelable: ProgressivePreloader['cancelable'],\n streamable: ProgressivePreloader['streamable'],\n tryAgainOnFail: ProgressivePreloader['tryAgainOnFail'],\n attachMethod: ProgressivePreloader['attachMethod']\n }>) {\n if(options) {\n safeAssign(this, options);\n }\n\n if(this.isUpload) {\n this.tryAgainOnFail = false;\n }\n }\n\n public constructContainer(options: Partial<{\n color: 'transparent',\n bold: boolean\n }> = {}) {\n if(!this.preloader) {\n this.preloader = document.createElement('div');\n this.preloader.classList.add('preloader-container');\n\n if(options.color) {\n this.preloader.classList.add('preloader-' + options.color);\n }\n\n if(options.bold) {\n this.preloader.classList.add('preloader-bold');\n }\n\n if(this.streamable) {\n this.preloader.classList.add('preloader-streamable');\n }\n }\n }\n\n public constructDownloadIcon() {\n this.constructContainer();\n }\n\n public construct() {\n this.construct = null;\n\n this.constructContainer();\n\n this.preloader.innerHTML = `\n <div class=\"you-spin-me-round\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"preloader-circular\" viewBox=\"${this.streamable ? '25 25 50 50' : '27 27 54 54'}\">\n <circle class=\"preloader-path-new\" cx=\"${this.streamable ? '50' : '54'}\" cy=\"${this.streamable ? '50' : '54'}\" r=\"${this.streamable ? 19 : 24}\" fill=\"none\" stroke-miterlimit=\"10\"/>\n </svg>\n </div>`;\n\n if(this.streamable) {\n this.totalLength = 118.61124420166016;\n } else {\n this.totalLength = 149.82473754882812;\n }\n\n if(this.cancelable) {\n this.preloader.innerHTML += `\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"preloader-close\" viewBox=\"0 0 24 24\">\n <g fill=\"none\" fill-rule=\"evenodd\">\n <polygon points=\"0 0 24 0 24 24 0 24\"/>\n <path fill=\"#000\" fill-rule=\"nonzero\" d=\"M5.20970461,5.38710056 L5.29289322,5.29289322 C5.65337718,4.93240926 6.22060824,4.90467972 6.61289944,5.20970461 L6.70710678,5.29289322 L12,10.585 L17.2928932,5.29289322 C17.6834175,4.90236893 18.3165825,4.90236893 18.7071068,5.29289322 C19.0976311,5.68341751 19.0976311,6.31658249 18.7071068,6.70710678 L13.415,12 L18.7071068,17.2928932 C19.0675907,17.6533772 19.0953203,18.2206082 18.7902954,18.6128994 L18.7071068,18.7071068 C18.3466228,19.0675907 17.7793918,19.0953203 17.3871006,18.7902954 L17.2928932,18.7071068 L12,13.415 L6.70710678,18.7071068 C6.31658249,19.0976311 5.68341751,19.0976311 5.29289322,18.7071068 C4.90236893,18.3165825 4.90236893,17.6834175 5.29289322,17.2928932 L10.585,12 L5.29289322,6.70710678 C4.93240926,6.34662282 4.90467972,5.77939176 5.20970461,5.38710056 L5.29289322,5.29289322 L5.20970461,5.38710056 Z\"/>\n </g>\n </svg>\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"preloader-download\" viewBox=\"0 0 24 24\">\n <g fill=\"none\" fill-rule=\"evenodd\">\n <polygon points=\"0 0 24 0 24 24 0 24\"/>\n <path fill=\"#000\" fill-rule=\"nonzero\" d=\"M5,19 L19,19 C19.5522847,19 20,19.4477153 20,20 C20,20.5128358 19.6139598,20.9355072 19.1166211,20.9932723 L19,21 L5,21 C4.44771525,21 4,20.5522847 4,20 C4,19.4871642 4.38604019,19.0644928 4.88337887,19.0067277 L5,19 L19,19 L5,19 Z M11.8833789,3.00672773 L12,3 C12.5128358,3 12.9355072,3.38604019 12.9932723,3.88337887 L13,4 L13,13.585 L16.2928932,10.2928932 C16.6533772,9.93240926 17.2206082,9.90467972 17.6128994,10.2097046 L17.7071068,10.2928932 C18.0675907,10.6533772 18.0953203,11.2206082 17.7902954,11.6128994 L17.7071068,11.7071068 L12.7071068,16.7071068 C12.3466228,17.0675907 11.7793918,17.0953203 11.3871006,16.7902954 L11.2928932,16.7071068 L6.29289322,11.7071068 C5.90236893,11.3165825 5.90236893,10.6834175 6.29289322,10.2928932 C6.65337718,9.93240926 7.22060824,9.90467972 7.61289944,10.2097046 L7.70710678,10.2928932 L11,13.585 L11,4 C11,3.48716416 11.3860402,3.06449284 11.8833789,3.00672773 L12,3 L11.8833789,3.00672773 Z\"/>\n </g>\n </svg>`;\n\n this.downloadSvg = this.preloader.lastElementChild as HTMLElement;\n this.cancelSvg = this.downloadSvg.previousElementSibling as any;\n } else {\n this.preloader.classList.add('preloader-swing');\n }\n\n this.circle = this.preloader.firstElementChild.firstElementChild.firstElementChild as SVGCircleElement;\n\n if(this.cancelable) {\n attachClickEvent(this.preloader, this.onClick);\n }\n }\n\n public onClick = (e?: Event) => {\n if(e) {\n cancelEvent(e);\n }\n\n if(this.preloader.classList.contains('manual')) {\n this.loadFunc?.(e);\n } else {\n this.promise?.cancel?.();\n }\n };\n\n public setDownloadFunction(func: ProgressivePreloader['loadFunc']) {\n this.loadFunc = func;\n }\n\n public setManual() {\n this.preloader.classList.add('manual');\n this.setProgress(0);\n }\n\n public attachPromise(promise: CancellablePromise<any>) {\n if(this.isUpload && this.promise) return;\n\n this.promise = promise;\n\n const tempId = --this.tempId;\n const startTime = Date.now();\n\n const onEnd = (err: Error) => {\n promise.notify = promise.notifyAll = null;\n\n if(tempId !== this.tempId) {\n return;\n }\n\n const elapsedTime = Date.now() - startTime;\n\n // console.log('[PP]: end', this.detached, performance.now());\n\n if(!err && this.cancelable) {\n this.setProgress(100);\n\n const delay = TRANSITION_TIME * 0.75;\n\n if(elapsedTime < delay) {\n this.detach();\n } else {\n setTimeout(() => { // * wait for transition complete\n if(tempId === this.tempId) {\n this.detach();\n }\n }, delay);\n }\n } else {\n if(this.tryAgainOnFail) {\n this.attach(this.preloader.parentElement);\n fastRaf(() => {\n this.setManual();\n });\n } else {\n this.detach();\n }\n }\n\n this.promise = promise = null;\n };\n\n promise\n .then(() => onEnd(null))\n .catch((err) => onEnd(err));\n\n if(promise.addNotifyListener) {\n promise.addNotifyListener((details: {done: number, total: number}) => {\n /* if(details.done >= details.total) {\n onEnd();\n } */\n\n if(tempId !== this.tempId) return;\n\n // console.log('preloader download', promise, details);\n const percents = details.done / details.total * 100;\n this.setProgress(percents);\n });\n }\n }\n\n public attach(elem: Element, reset = false, promise?: CancellablePromise<any>) {\n this.construct?.();\n\n if(this.preloader.parentElement) {\n this.preloader.classList.remove('manual');\n }\n\n this.detached = false;\n\n if(promise/* && false */) {\n this.attachPromise(promise);\n }\n\n let useRafs = 0;\n if(this.detached || this.preloader.parentElement !== elem) {\n useRafs = isInDOM(this.preloader) ? 1 : 2;\n if(this.preloader.parentElement !== elem) {\n elem[this.attachMethod](this.preloader);\n }\n }\n\n SetTransition({\n element: this.preloader,\n className: 'is-visible',\n forwards: true,\n duration: TRANSITION_TIME,\n useRafs\n });\n\n if(this.cancelable && reset) {\n this.setProgress(0);\n }\n }\n\n public detach() {\n if(this.detached) {\n return;\n }\n // return;\n\n this.detached = true;\n\n // return;\n\n if(this.preloader?.parentElement) {\n /* setTimeout(() => */// fastRaf(() => {\n /* if(!this.detached) return;\n this.detached = true; */\n\n // fastRaf(() => {\n // console.log('[PP]: detach after rAF', this.detached, performance.now());\n\n // if(!this.detached || !this.preloader.parentElement) {\n // return;\n // }\n\n SetTransition({\n element: this.preloader,\n className: 'is-visible',\n forwards: false,\n duration: TRANSITION_TIME,\n onTransitionEnd: () => {\n this.preloader.remove();\n },\n useRafs: 1\n });\n // });\n // })/* , 5e3) */;\n }\n }\n\n public setProgress(percents: number) {\n if(!this.totalLength && !isInDOM(this.circle)) {\n return;\n }\n\n if(percents === 0) {\n this.circle.style.strokeDasharray = '';\n return;\n }\n\n try {\n this.totalLength ||= this.circle.getTotalLength();\n\n // console.log('setProgress', (percents / 100 * totalLength));\n this.circle.style.strokeDasharray = '' + Math.max(5, percents / 100 * this.totalLength) + ', ' + this.totalLength;\n } catch(err) {}\n }\n}\n","/*\nThis file is part of Telegram Desktop,\nthe official desktop application for the Telegram messaging service.\nFor license and copyright information please follow this link:\nhttps://github.com/telegramdesktop/tdesktop/blob/master/LEGAL\n*/\n\nimport accumulate from '../helpers/array/accumulate';\nimport clamp from '../helpers/number/clamp';\n\ntype Size = {w: number, h: number};\nexport type GroupMediaLayout = {\n geometry: {\n x: number,\n y: number,\n width: number,\n height: number\n },\n sides: number\n};\ntype Attempt = {\n lineCounts: number[],\n heights: number[]\n};\nexport const RectPart = {\n None: 0,\n Top: 1,\n Right: 2,\n Bottom: 4,\n Left: 8\n};\n\n// https://github.com/telegramdesktop/tdesktop/blob/4669c07dc5335cbf4795bbbe5b0ab7c007b9aee2/Telegram/SourceFiles/ui/grouped_layout.cpp\nexport class Layouter {\n private count: number;\n private ratios: number[];\n private proportions: string;\n private averageRatio: number;\n private maxSizeRatio: number;\n\n constructor(private sizes: Size[], private maxWidth: number, private minWidth: number, private spacing: number, private maxHeight = maxWidth) {\n this.count = sizes.length;\n this.ratios = Layouter.countRatios(sizes);\n this.proportions = Layouter.countProportions(this.ratios);\n this.averageRatio = accumulate(this.ratios, 1) / this.count; // warn\n this.maxSizeRatio = maxWidth / this.maxHeight;\n }\n\n public layout(): GroupMediaLayout[] {\n if(!this.count) return [];\n // else if(this.count === 1) return this.layoutOne();\n\n if(this.count >= 5 || this.ratios.find((r) => r > 2)) {\n return new ComplexLayouter(this.ratios, this.averageRatio, this.maxWidth, this.minWidth, this.spacing).layout();\n }\n\n if(this.count === 2) return this.layoutTwo();\n else if(this.count === 3) return this.layoutThree();\n return this.layoutFour();\n }\n\n private layoutTwo(): ReturnType<Layouter['layout']> {\n if((this.proportions === 'ww') &&\n (this.averageRatio > 1.4 * this.maxSizeRatio) &&\n (this.ratios[1] - this.ratios[0] < 0.2)) {\n return this.layoutTwoTopBottom();\n } else if(this.proportions === 'ww' || this.proportions === 'qq') {\n return this.layoutTwoLeftRightEqual();\n }\n return this.layoutTwoLeftRight();\n }\n\n private layoutThree(): ReturnType<Layouter['layout']> {\n // console.log('layoutThree:', this);\n if(this.proportions[0] === 'n') {\n return this.layoutThreeLeftAndOther();\n }\n return this.layoutThreeTopAndOther();\n }\n\n private layoutFour(): ReturnType<Layouter['layout']> {\n if(this.proportions[0] === 'w') {\n return this.layoutFourTopAndOther();\n }\n return this.layoutFourLeftAndOther();\n }\n\n private layoutTwoTopBottom(): ReturnType<Layouter['layout']> {\n const width = this.maxWidth;\n const height = Math.round(Math.min(\n width / this.ratios[0],\n Math.min(\n width / this.ratios[1],\n (this.maxHeight - this.spacing) / 2)));\n\n return [\n {\n geometry: {x: 0, y: 0, width, height},\n sides: RectPart.Left | RectPart.Top | RectPart.Right\n },\n {\n geometry: {x: 0, y: height + this.spacing, width, height},\n sides: RectPart.Left | RectPart.Bottom | RectPart.Right\n }\n ];\n }\n\n private layoutTwoLeftRightEqual(): ReturnType<Layouter['layout']> {\n const width = (this.maxWidth - this.spacing) / 2;\n const height = Math.round(Math.min(\n width / this.ratios[0],\n Math.min(width / this.ratios[1], this.maxHeight * 1)));\n\n return [\n {\n geometry: {x: 0, y: 0, width, height},\n sides: RectPart.Top | RectPart.Left | RectPart.Bottom\n },\n {\n geometry: {x: width + this.spacing, y: 0, width, height},\n sides: RectPart.Top | RectPart.Right | RectPart.Bottom\n }\n ];\n }\n\n private layoutTwoLeftRight(): ReturnType<Layouter['layout']> {\n const minimalWidth = Math.round(this.minWidth * 1.5);\n const secondWidth = Math.min(\n Math.round(Math.max(\n 0.4 * (this.maxWidth - this.spacing),\n (this.maxWidth - this.spacing) / this.ratios[0] /\n (1 / this.ratios[0] + 1 / this.ratios[1]))),\n this.maxWidth - this.spacing - minimalWidth);\n const firstWidth = this.maxWidth -\n secondWidth -\n this.spacing;\n const height = Math.min(\n this.maxHeight,\n Math.round(Math.min(\n firstWidth / this.ratios[0],\n secondWidth / this.ratios[1])));\n\n return [\n {\n geometry: {x: 0, y: 0, width: firstWidth, height},\n sides: RectPart.Top | RectPart.Left | RectPart.Bottom\n },\n {\n geometry: {x: firstWidth + this.spacing, y: 0, width: secondWidth, height},\n sides: RectPart.Top | RectPart.Right | RectPart.Bottom\n }\n ];\n }\n\n private layoutThreeLeftAndOther(): ReturnType<Layouter['layout']> {\n const firstHeight = this.maxHeight;\n const thirdHeight = Math.round(Math.min(\n (this.maxHeight - this.spacing) / 2.,\n (this.ratios[1] * (this.maxWidth - this.spacing) /\n (this.ratios[2] + this.ratios[1]))));\n const secondHeight = firstHeight -\n thirdHeight -\n this.spacing;\n const rightWidth = Math.max(\n this.minWidth,\n Math.round(Math.min(\n (this.maxWidth - this.spacing) / 2.,\n Math.min(\n thirdHeight * this.ratios[2],\n secondHeight * this.ratios[1]))));\n const leftWidth = Math.min(\n Math.round(firstHeight * this.ratios[0]),\n this.maxWidth - this.spacing - rightWidth);\n\n return [\n {\n geometry: {x: 0, y: 0, width: leftWidth, height: firstHeight},\n sides: RectPart.Top | RectPart.Left | RectPart.Bottom\n },\n {\n geometry: {x: leftWidth + this.spacing, y: 0, width: rightWidth, height: secondHeight},\n sides: RectPart.Top | RectPart.Right\n },\n {\n geometry: {x: leftWidth + this.spacing, y: secondHeight + this.spacing, width: rightWidth, height: thirdHeight},\n sides: RectPart.Bottom | RectPart.Right\n }\n ];\n }\n\n private layoutThreeTopAndOther(): ReturnType<Layouter['layout']> {\n const firstWidth = this.maxWidth;\n const firstHeight = Math.round(Math.min(\n firstWidth / this.ratios[0],\n (this.maxHeight - this.spacing) * 0.66));\n const secondWidth = (this.maxWidth - this.spacing) / 2;\n const secondHeight = Math.min(\n this.maxHeight - firstHeight - this.spacing,\n Math.round(Math.min(\n secondWidth / this.ratios[1],\n secondWidth / this.ratios[2])));\n const thirdWidth = firstWidth - secondWidth - this.spacing;\n\n return [\n {\n geometry: {x: 0, y: 0, width: firstWidth, height: firstHeight},\n sides: RectPart.Left | RectPart.Top | RectPart.Right\n },\n {\n geometry: {x: 0, y: firstHeight + this.spacing, width: secondWidth, height: secondHeight},\n sides: RectPart.Bottom | RectPart.Left\n },\n {\n geometry: {x: secondWidth + this.spacing, y: firstHeight + this.spacing, width: thirdWidth, height: secondHeight},\n sides: RectPart.Bottom | RectPart.Right\n }\n ];\n }\n\n private layoutFourTopAndOther(): ReturnType<Layouter['layout']> {\n const w = this.maxWidth;\n const h0 = Math.round(Math.min(\n w / this.ratios[0],\n (this.maxHeight - this.spacing) * 0.66));\n const h = Math.round(\n (this.maxWidth - 2 * this.spacing) /\n (this.ratios[1] + this.ratios[2] + this.ratios[3]));\n const w0 = Math.max(\n this.minWidth,\n Math.round(Math.min(\n (this.maxWidth - 2 * this.spacing) * 0.4,\n h * this.ratios[1])));\n const w2 = Math.round(Math.max(\n Math.max(\n this.minWidth * 1.,\n (this.maxWidth - 2 * this.spacing) * 0.33),\n h * this.ratios[3]));\n const w1 = w - w0 - w2 - 2 * this.spacing;\n const h1 = Math.min(\n this.maxHeight - h0 - this.spacing,\n h);\n\n return [\n {\n geometry: {x: 0, y: 0, width: w, height: h0},\n sides: RectPart.Left | RectPart.Top | RectPart.Right\n },\n {\n geometry: {x: 0, y: h0 + this.spacing, width: w0, height: h1},\n sides: RectPart.Bottom | RectPart.Left\n },\n {\n geometry: {x: w0 + this.spacing, y: h0 + this.spacing, width: w1, height: h1},\n sides: RectPart.Bottom\n },\n {\n geometry: {x: w0 + this.spacing + w1 + this.spacing, y: h0 + this.spacing, width: w2, height: h1},\n sides: RectPart.Right | RectPart.Bottom\n }\n ];\n }\n\n private layoutFourLeftAndOther(): ReturnType<Layouter['layout']> {\n const h = this.maxHeight;\n const w0 = Math.round(Math.min(\n h * this.ratios[0],\n (this.maxWidth - this.spacing) * 0.6));\n\n const w = Math.round(\n (this.maxHeight - 2 * this.spacing) /\n (1. / this.ratios[1] + 1. / this.ratios[2] + 1. / this.ratios[3])\n );\n const h0 = Math.round(w / this.ratios[1]);\n const h1 = Math.round(w / this.ratios[2]);\n const h2 = h - h0 - h1 - 2 * this.spacing;\n const w1 = Math.max(\n this.minWidth,\n Math.min(this.maxWidth - w0 - this.spacing, w));\n\n return [\n {\n geometry: {x: 0, y: 0, width: w0, height: h},\n sides: RectPart.Top | RectPart.Left | RectPart.Bottom\n },\n {\n geometry: {x: w0 + this.spacing, y: 0, width: w1, height: h0},\n sides: RectPart.Top | RectPart.Right\n },\n {\n geometry: {x: w0 + this.spacing, y: h0 + this.spacing, width: w1, height: h1},\n sides: RectPart.Right\n },\n {\n geometry: {x: w0 + this.spacing, y: h0 + h1 + 2 * this.spacing, width: w1, height: h2},\n sides: RectPart.Bottom | RectPart.Right\n }\n ];\n }\n\n private static countRatios(sizes: Size[]) {\n return sizes.map((size) => size.w / size.h);\n }\n\n private static countProportions(ratios: number[]) {\n return ratios.map((ratio) => (ratio > 1.2) ? 'w' : (ratio < 0.8) ? 'n' : 'q').join('');\n }\n}\n\nclass ComplexLayouter {\n private ratios: number[];\n private count: number;\n\n constructor(ratios: number[], private averageRatio: number, private maxWidth: number, private minWidth: number, private spacing: number, private maxHeight = maxWidth * 4 / 3) {\n this.ratios = ComplexLayouter.cropRatios(ratios, averageRatio);\n this.count = ratios.length;\n }\n\n private static cropRatios(ratios: number[], averageRatio: number) {\n const kMaxRatio = 2.75;\n const kMinRatio = 0.6667;\n return ratios.map((ratio) => {\n return averageRatio > 1.1 ?\n clamp(ratio, 1., kMaxRatio) :\n clamp(ratio, kMinRatio, 1.);\n });\n }\n\n public layout(): GroupMediaLayout[] {\n const result = new Array<GroupMediaLayout>(this.count);\n\n const attempts: Attempt[] = [];\n const multiHeight = (offset: number, count: number) => {\n const ratios = this.ratios.slice(offset, offset + count); // warn\n const sum = accumulate(ratios, 0);\n return (this.maxWidth - (count - 1) * this.spacing) / sum;\n };\n const pushAttempt = (lineCounts: number[]) => {\n const heights: number[] = [];\n let offset = 0;\n for(const count of lineCounts) {\n heights.push(multiHeight(offset, count));\n offset += count;\n }\n attempts.push({lineCounts, heights}); // warn\n };\n\n for(let first = 1; first !== this.count; ++first) {\n const second = this.count - first;\n if(first > 3 || second > 3) {\n continue;\n }\n pushAttempt([first, second]);\n }\n for(let first = 1; first !== this.count - 1; ++first) {\n for(let second = 1; second !== this.count - first; ++second) {\n const third = this.count - first - second;\n if((first > 3) ||\n (second > ((this.averageRatio < 0.85) ? 4 : 3)) ||\n (third > 3)) {\n continue;\n }\n pushAttempt([first, second, third]);\n }\n }\n for(let first = 1; first !== this.count - 1; ++first) {\n for(let second = 1; second !== this.count - first; ++second) {\n for(let third = 1; third !== this.count - first - second; ++third) {\n const fourth = this.count - first - second - third;\n if(first > 3 || second > 3 || third > 3 || fourth > 3) {\n continue;\n }\n pushAttempt([first, second, third, fourth]);\n }\n }\n }\n\n let optimalAttempt: Attempt = null;\n let optimalDiff = 0;\n for(const attempt of attempts) {\n const {heights, lineCounts: counts} = attempt;\n const lineCount = counts.length;\n const totalHeight = accumulate(heights, 0) +\n this.spacing * (lineCount - 1);\n const minLineHeight = Math.min(...heights);\n const maxLineHeight = Math.max(...heights);\n const bad1 = (minLineHeight < this.minWidth) ? 1.5 : 1;\n const bad2 = (() => {\n for(let line = 1; line !== lineCount; ++line) {\n if(counts[line - 1] > counts[line]) {\n return 1.5;\n }\n }\n return 1.;\n })();\n const diff = Math.abs(totalHeight - this.maxHeight) * bad1 * bad2;\n if(!optimalAttempt || diff < optimalDiff) {\n optimalAttempt = attempt;\n optimalDiff = diff;\n }\n }\n\n const optimalCounts = optimalAttempt.lineCounts;\n const optimalHeights = optimalAttempt.heights;\n const rowCount = optimalCounts.length;\n\n let index = 0;\n let y = 0;\n for(let row = 0; row !== rowCount; ++row) {\n const colCount = optimalCounts[row];\n const lineHeight = optimalHeights[row];\n const height = Math.round(lineHeight);\n\n let x = 0;\n for(let col = 0; col !== colCount; ++col) {\n const sides = RectPart.None |\n (row === 0 ? RectPart.Top : RectPart.None) |\n (row === rowCount - 1 ? RectPart.Bottom : RectPart.None) |\n (col === 0 ? RectPart.Left : RectPart.None) |\n (col === colCount - 1 ? RectPart.Right : RectPart.None);\n\n const ratio = this.ratios[index];\n const width = (col === colCount - 1) ?\n (this.maxWidth - x) :\n Math.round(ratio * lineHeight);\n result[index] = {\n geometry: {x, y, width, height},\n sides\n };\n\n x += width + this.spacing;\n ++index;\n }\n y += height + this.spacing;\n }\n\n return result;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {Layouter, RectPart} from './groupedLayout';\n\nexport default function prepareAlbum(options: {\n container: HTMLElement,\n items: {w: number, h: number}[],\n maxWidth: number,\n minWidth: number,\n spacing: number,\n maxHeight?: number,\n forMedia?: true\n}) {\n const layouter = new Layouter(options.items, options.maxWidth, options.minWidth, options.spacing, options.maxHeight);\n const layout = layouter.layout();\n\n const widthItem = layout.find((item) => item.sides & RectPart.Right);\n const width = widthItem.geometry.width + widthItem.geometry.x;\n\n const heightItem = layout.find((item) => item.sides & RectPart.Bottom);\n const height = heightItem.geometry.height + heightItem.geometry.y;\n\n const container = options.container;\n container.style.width = width + 'px';\n container.style.height = height + 'px';\n const children = container.children;\n\n layout.forEach(({geometry, sides}, idx) => {\n let div: HTMLElement;\n div = children[idx] as HTMLElement;\n if(!div) {\n div = document.createElement('div');\n container.append(div);\n }\n\n div.classList.add('album-item', 'grouped-item');\n\n div.style.width = (geometry.width / width * 100) + '%';\n div.style.height = (geometry.height / height * 100) + '%';\n div.style.top = (geometry.y / height * 100) + '%';\n div.style.left = (geometry.x / width * 100) + '%';\n\n if(sides & RectPart.Left && sides & RectPart.Top) {\n div.style.borderTopLeftRadius = 'inherit';\n }\n\n if(sides & RectPart.Left && sides & RectPart.Bottom) {\n div.style.borderBottomLeftRadius = 'inherit';\n }\n\n if(sides & RectPart.Right && sides & RectPart.Top) {\n div.style.borderTopRightRadius = 'inherit';\n }\n\n if(sides & RectPart.Right && sides & RectPart.Bottom) {\n div.style.borderBottomRightRadius = 'inherit';\n }\n\n if(options.forMedia) {\n const mediaDiv = document.createElement('div');\n mediaDiv.classList.add('album-item-media');\n\n div.append(mediaDiv);\n }\n\n // @ts-ignore\n // div.style.backgroundColor = '#' + Math.floor(Math.random() * (2 ** 24 - 1)).toString(16).padStart(6, '0');\n });\n\n /* if(options.forMedia) {\n layout.forEach((_, i) => {\n const mediaDiv = document.createElement('div');\n mediaDiv.classList.add('album-item-media');\n\n options.container.children[i].append(mediaDiv);\n });\n } */\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {PeerPhotoSize} from '../lib/appManagers/appAvatarsManager';\nimport getPreviewURLFromBytes from '../helpers/bytes/getPreviewURLFromBytes';\nimport {renderImageFromUrlPromise} from '../helpers/dom/renderImageFromUrl';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport setInnerHTML from '../helpers/dom/setInnerHTML';\nimport {recordPromise} from '../helpers/recordPromise';\nimport sequentialDom from '../helpers/sequentialDom';\nimport {UserProfilePhoto, ChatPhoto, User, Chat} from '../layer';\nimport getPeerColorById from '../lib/appManagers/utils/peers/getPeerColorById';\nimport getPeerPhoto from '../lib/appManagers/utils/peers/getPeerPhoto';\nimport {NULL_PEER_ID, REPLIES_PEER_ID} from '../lib/mtproto/mtproto_config';\nimport wrapAbbreviation from '../lib/richTextProcessor/wrapAbbreviation';\nimport rootScope from '../lib/rootScope';\nimport getPeerInitials from './wrappers/getPeerInitials';\nimport {wrapTopicIcon} from './wrappers/messageActionTextNewUnsafe';\nimport makeError from '../helpers/makeError';\nimport noop from '../helpers/noop';\nimport liteMode from '../helpers/liteMode';\n\nexport async function putAvatar(\n div: HTMLElement,\n peerId: PeerId,\n photo: UserProfilePhoto.userProfilePhoto | ChatPhoto.chatPhoto,\n size: PeerPhotoSize,\n img = new Image(),\n onlyThumb = false\n) {\n const r = await rootScope.managers.acknowledged.appAvatarsManager.loadAvatar(peerId, photo, size);\n const loadPromise = r.result;\n const cached = r.cached;\n\n img.classList.add('avatar-photo');\n\n let renderThumbPromise: Promise<void>;\n let callback: () => void;\n let thumbImage: HTMLImageElement;\n if(cached) {\n // смотри в misc.ts: renderImageFromUrl\n callback = () => {\n replaceContent(div, img);\n div.dataset.color = '';\n };\n } else {\n const animate = liteMode.isAvailable('animations');\n if(animate) {\n img.classList.add('fade-in');\n }\n\n let isFullLoaded = false;\n if(size === 'photo_big') { // let's load small photo first\n const res = await putAvatar(div, peerId, photo, 'photo_small');\n renderThumbPromise = res.loadThumbPromise || res.loadPromise;\n thumbImage = res.thumbImage;\n } else if(photo.stripped_thumb) {\n thumbImage = new Image();\n div.classList.add('avatar-relative');\n thumbImage.classList.add('avatar-photo', 'avatar-photo-thumbnail');\n const url = getPreviewURLFromBytes(photo.stripped_thumb);\n renderThumbPromise = renderImageFromUrlPromise(thumbImage, url).then(() => {\n if(isFullLoaded) {\n return;\n }\n\n replaceContent(div, thumbImage);\n });\n }\n\n callback = () => {\n isFullLoaded = true;\n\n if(thumbImage) {\n div.append(img);\n } else {\n replaceContent(div, img);\n }\n\n setTimeout(() => {\n if(div.childElementCount) {\n sequentialDom.mutateElement(img, () => {\n div.dataset.color = '';\n\n if(animate) {\n img.classList.remove('fade-in');\n }\n\n thumbImage?.remove();\n });\n }\n }, animate ? 200 : 0);\n };\n }\n\n const renderPromise = loadPromise\n .then((url) => renderImageFromUrlPromise(img, url/* , !cached */))\n .then(callback);\n\n renderThumbPromise && await renderThumbPromise.catch(noop);\n\n return {\n cached,\n loadPromise: renderPromise,\n loadThumbPromise: cached ? renderPromise : renderThumbPromise || Promise.resolve(),\n thumbImage\n };\n}\n\nfunction set(\n div: HTMLElement,\n innerHTML: Parameters<typeof setInnerHTML>[1],\n color: string,\n icon?: string,\n isForum?: boolean,\n isTopic?: boolean\n) {\n setInnerHTML(div, innerHTML);\n div.dataset.color = color;\n div.classList.remove('tgico-saved', 'tgico-deletedaccount', 'tgico-reply_filled', 'is-forum', 'is-topic');\n icon && div.classList.add(icon);\n isForum && div.classList.add('is-forum');\n isTopic && div.classList.add('is-topic');\n}\n\n// peerId === peerId || title\nexport default async function putPhoto({\n div,\n peerId,\n isDialog = false,\n title = '',\n onlyThumb = false,\n isBig,\n threadId,\n wrapOptions = {}\n}: {\n div: HTMLElement,\n peerId: PeerId,\n isDialog?: boolean,\n title?: string,\n onlyThumb?: boolean,\n isBig?: boolean,\n threadId?: number,\n wrapOptions?: WrapSomethingOptions\n}) {\n const myId = rootScope.myId;\n\n if(peerId === myId && isDialog) {\n set(div, '', '', 'tgico-saved');\n return;\n }\n\n const managers = rootScope.managers;\n\n if(threadId) {\n const topic = await managers.dialogsStorage.getForumTopic(peerId, threadId);\n set(div, '', '', undefined, undefined, true);\n\n if(wrapOptions.customEmojiSize) {\n div.style.setProperty('--size', wrapOptions.customEmojiSize.width + 'px');\n }\n\n return wrapTopicIcon({\n ...wrapOptions,\n topic,\n lazyLoadQueue: false\n }).then((icon) => {\n div.replaceChildren(icon);\n });\n }\n\n const peer = await managers.appPeersManager.getPeer(peerId);\n if(peerId !== NULL_PEER_ID && peerId.isUser() && (peer as User.user)?.pFlags?.deleted) {\n set(div, '', getPeerColorById(peerId), 'tgico-deletedaccount');\n return;\n }\n\n const isForum = !!(peer as Chat.channel)?.pFlags?.forum;\n const size: PeerPhotoSize = isBig ? 'photo_big' : 'photo_small';\n const photo = getPeerPhoto(peer);\n const avatarAvailable = !!photo;\n const avatarRendered = !!div.firstElementChild && !(div.firstElementChild as HTMLElement).classList.contains('emoji');\n if(!avatarAvailable || !avatarRendered || !(await managers.appAvatarsManager.isAvatarCached(peerId, size))) {\n let color = '';\n if(peerId && (peerId !== myId || !isDialog)) {\n color = getPeerColorById(peerId);\n }\n\n if(peerId === REPLIES_PEER_ID) {\n set(div, '', color, 'tgico-reply_filled');\n return;\n }\n\n const abbr = title ? wrapAbbreviation(title) : getPeerInitials(peer);\n set(div, abbr, color, '', isForum);\n // return Promise.resolve(true);\n }\n\n if(avatarAvailable/* && false */) {\n const promise = putAvatar(div, peerId, photo, size, undefined, onlyThumb);\n // recordPromise(promise, 'putAvatar-' + peerId);\n return promise;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {Chat, User} from '../../layer';\nimport wrapAbbreviation from '../../lib/richTextProcessor/wrapAbbreviation';\n\nexport default function getPeerInitials(peer: Chat | User) {\n let str = '';\n if(peer) {\n str = (peer as Chat.chat).title ?? [\n (peer as User.user).first_name,\n (peer as User.user).last_name\n ].filter(Boolean).join(' ');\n }\n\n return wrapAbbreviation(str);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MOUNT_CLASS_TO} from '../config/debug';\n\nexport function putPreloader(elem: Element, returnDiv = false): HTMLElement {\n const html = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"preloader-circular\" viewBox=\"25 25 50 50\">\n <circle class=\"preloader-path\" cx=\"50\" cy=\"50\" r=\"20\" fill=\"none\" stroke-miterlimit=\"10\"/>\n </svg>`;\n\n if(returnDiv) {\n const div = document.createElement('div');\n div.classList.add('preloader');\n div.innerHTML = html;\n\n if(elem) {\n elem.appendChild(div);\n }\n\n return div;\n }\n\n elem.insertAdjacentHTML('beforeend', html);\n return elem.lastElementChild as HTMLElement;\n}\n\nMOUNT_CLASS_TO.putPreloader = putPreloader;\n\nexport function setButtonLoader(elem: HTMLButtonElement, icon = 'check') {\n elem.classList.remove('tgico-' + icon);\n elem.disabled = true;\n putPreloader(elem);\n\n return () => {\n elem.replaceChildren();\n elem.classList.add('tgico-' + icon);\n elem.removeAttribute('disabled');\n };\n}\n\n/* export function parseMenuButtonsTo(to: {[name: string]: HTMLElement}, elements: HTMLCollection | NodeListOf<HTMLElement>) {\n Array.from(elements).forEach((el) => {\n const match = el.className.match(/(?:^|\\s)menu-(.+?)(?:$|\\s)/);\n if(!match) return;\n to[match[1]] = el as HTMLElement;\n });\n} */\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport simulateEvent from '../helpers/dom/dispatchEvent';\nimport getDeepProperty from '../helpers/object/getDeepProperty';\nimport {LangPackKey, _i18n} from '../lib/langPack';\nimport apiManagerProxy from '../lib/mtproto/mtprotoworker';\nimport rootScope from '../lib/rootScope';\n\nexport default class RadioField {\n public input: HTMLInputElement;\n public label: HTMLLabelElement;\n public main: HTMLElement;\n\n constructor(options: {\n text?: string,\n langKey?: LangPackKey,\n name: string,\n value?: string,\n stateKey?: string,\n alignRight?: boolean\n }) {\n const label = this.label = document.createElement('label');\n label.classList.add('radio-field');\n\n if(options.alignRight) {\n label.classList.add('radio-field-right');\n }\n\n const input = this.input = document.createElement('input');\n input.type = 'radio';\n /* input.id = */input.name = 'input-radio-' + options.name;\n\n if(options.value) {\n input.value = options.value;\n\n if(options.stateKey) {\n apiManagerProxy.getState().then((state) => {\n input.checked = getDeepProperty(state, options.stateKey) === options.value;\n });\n\n input.addEventListener('change', () => {\n rootScope.managers.appStateManager.setByKey(options.stateKey, options.value);\n });\n }\n }\n\n const main = this.main = document.createElement('div');\n main.classList.add('radio-field-main');\n\n if(options.text) {\n main.innerHTML = options.text;\n /* const caption = document.createElement('div');\n caption.classList.add('radio-field-main-caption');\n caption.innerHTML = text;\n\n if(subtitle) {\n label.classList.add('radio-field-with-subtitle');\n caption.insertAdjacentHTML('beforeend', `<div class=\"radio-field-main-subtitle\">${subtitle}</div>`);\n }\n\n main.append(caption); */\n } else if(options.langKey) {\n _i18n(main, options.langKey);\n }\n\n label.append(input, main);\n }\n\n get checked() {\n return this.input.checked;\n }\n\n set checked(checked: boolean) {\n this.setValueSilently(checked);\n simulateEvent(this.input, 'change');\n }\n\n public setValueSilently(checked: boolean) {\n this.input.checked = checked;\n }\n};\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function RadioForm(radios: {container: HTMLElement, input: HTMLInputElement}[], onChange: (value: string, event: Event) => void) {\n const form = document.createElement('form');\n\n radios.forEach((r) => {\n const {container, input} = r;\n form.append(container);\n input.addEventListener('change', (e) => {\n if(input.checked) {\n onChange(input.value, e);\n }\n });\n });\n\n return form;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport attachGrabListeners, {GrabEvent} from '../helpers/dom/attachGrabListeners';\nimport clamp from '../helpers/number/clamp';\nimport safeAssign from '../helpers/object/safeAssign';\n\nexport default class RangeSelector {\n public container: HTMLDivElement;\n protected filled: HTMLDivElement;\n protected seek: HTMLInputElement;\n\n public mousedown = false;\n protected rect: DOMRect;\n protected _removeListeners: () => void;\n\n private events: Partial<{\n // onMouseMove: ProgressLine['onMouseMove'],\n onMouseDown: RangeSelector['onMouseDown'],\n onMouseUp: RangeSelector['onMouseUp'],\n onScrub: (value: number) => void\n }> = {};\n\n protected decimals: number;\n\n protected step: number;\n protected min: number;\n protected max: number;\n protected withTransition = false;\n protected useTransform = false;\n protected vertical = false;\n\n constructor(\n options: {\n step: RangeSelector['step'],\n min: RangeSelector['min'],\n max: RangeSelector['max'],\n withTransition?: RangeSelector['withTransition'],\n useTransform?: RangeSelector['useTransform'],\n vertical?: RangeSelector['vertical']\n },\n value = 0\n ) {\n safeAssign(this, options);\n\n this.container = document.createElement('div');\n this.container.classList.add('progress-line');\n\n // there is no sense in using transition with transform, because it is updating every frame\n if(this.useTransform) {\n this.container.classList.add('use-transform');\n } else if(this.withTransition) {\n this.container.classList.add('with-transition');\n }\n\n this.filled = document.createElement('div');\n this.filled.classList.add('progress-line__filled');\n\n const seek = this.seek = document.createElement('input');\n seek.classList.add('progress-line__seek');\n // seek.setAttribute('max', '0');\n seek.type = 'range';\n seek.step = '' + this.step;\n seek.min = '' + this.min;\n seek.max = '' + this.max;\n seek.value = '' + value;\n\n if(value) {\n this.setProgress(value);\n }\n\n const stepStr = '' + this.step;\n const index = stepStr.indexOf('.');\n this.decimals = index === -1 ? 0 : stepStr.length - index - 1;\n\n // this.setListeners();\n\n this.container.append(this.filled, seek);\n }\n\n get value() {\n return +this.seek.value;\n }\n\n public setHandlers(events: RangeSelector['events']) {\n this.events = events;\n }\n\n protected onMouseMove = (event: GrabEvent) => {\n this.scrub(event);\n };\n\n protected onMouseDown = (event: GrabEvent) => {\n this.rect = this.container.getBoundingClientRect();\n this.mousedown = true;\n this.scrub(event);\n this.container.classList.add('is-focused');\n this.events?.onMouseDown && this.events.onMouseDown(event);\n };\n\n protected onMouseUp = (event: GrabEvent) => {\n this.mousedown = false;\n this.container.classList.remove('is-focused');\n this.events?.onMouseUp && this.events.onMouseUp(event);\n };\n\n public setListeners() {\n this.seek.addEventListener('input', this.onInput);\n this._removeListeners = attachGrabListeners(this.container, this.onMouseDown, this.onMouseMove, this.onMouseUp);\n }\n\n public onInput = () => {\n const value = +this.seek.value;\n this.setFilled(value);\n this.events?.onScrub && this.events.onScrub(value);\n };\n\n public setProgress(value: number) {\n this.seek.value = '' + value;\n this.setFilled(+this.seek.value); // clamp\n }\n\n public addProgress(value: number) {\n this.seek.value = '' + (+this.seek.value + value);\n this.setFilled(+this.seek.value); // clamp\n }\n\n public setFilled(value: number) {\n let percents = (value - this.min) / (this.max - this.min);\n percents = clamp(percents, 0, 1);\n\n // using scaleX and width even with vertical because it will be rotated\n if(this.useTransform) {\n this.filled.style.transform = `scaleX(${percents})`;\n } else {\n this.filled.style.width = (percents * 100) + '%';\n }\n }\n\n protected scrub(event: GrabEvent) {\n const rectMax = this.vertical ? this.rect.height : this.rect.width;\n const offsetAxisValue = clamp(this.vertical ? -(event.y - this.rect.bottom) : event.x - this.rect.left, 0, rectMax);\n\n let value = this.min + (offsetAxisValue / rectMax * (this.max - this.min));\n\n if((value - this.min) < ((this.max - this.min) / 2)) {\n value -= this.step / 10;\n }\n\n value = +value.toFixed(this.decimals);\n value = clamp(value, this.min, this.max);\n\n // this.seek.value = '' + value;\n // this.onInput();\n\n this.setProgress(value);\n this.events?.onScrub && this.events.onScrub(value);\n\n return value;\n }\n\n public removeListeners() {\n if(this._removeListeners) {\n this._removeListeners();\n this._removeListeners = null;\n }\n\n this.seek.removeEventListener('input', this.onInput);\n\n this.events = {};\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport sequentialDom from '../helpers/sequentialDom';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport rootScope from '../lib/rootScope';\nimport findUpAsChild from '../helpers/dom/findUpAsChild';\nimport {fastRaf} from '../helpers/schedulers';\nimport liteMode from '../helpers/liteMode';\n\nlet rippleClickId = 0;\nexport default function ripple(\n elem: HTMLElement,\n callback: (id: number) => Promise<boolean | void> = () => Promise.resolve(),\n onEnd: (id: number) => void = null,\n prepend = false,\n attachListenerTo = elem\n) {\n // return;\n if(elem.querySelector('.c-ripple')) return;\n elem.classList.add('rp');\n\n const r = document.createElement('div');\n r.classList.add('c-ripple');\n\n const isSquare = elem.classList.contains('rp-square');\n if(isSquare) {\n r.classList.add('is-square');\n }\n\n elem[prepend ? 'prepend' : 'append'](r);\n\n let handler: () => void;\n // let animationEndPromise: Promise<number>;\n const drawRipple = (clientX: number, clientY: number) => {\n const startTime = Date.now();\n const circle = document.createElement('div');\n\n const clickId = rippleClickId++;\n\n // console.log('ripple drawRipple');\n\n // const auto = elem.classList.contains('row-sortable') && !elem.classList.contains('cant-sort');\n const auto = false;\n const duration = (auto ? .3 : +window.getComputedStyle(r).getPropertyValue('--ripple-duration').replace('s', '')) * 1000;\n // console.log('ripple duration', duration);\n\n const _handler = handler = () => {\n // handler = () => animationEndPromise.then((duration) => {\n // console.log('ripple animation was:', duration);\n\n // const duration = isSquare || mediaSizes.isMobile ? 200 : 700;\n // return;\n const elapsedTime = Date.now() - startTime;\n const cb = () => {\n // console.log('ripple elapsedTime total pre-remove:', Date.now() - startTime);\n sequentialDom.mutate(() => {\n circle.remove();\n });\n\n onEnd?.(clickId);\n };\n if(elapsedTime < duration) {\n const delay = Math.max(duration - elapsedTime, duration / 2);\n setTimeout(() => circle.classList.add('hiding'), Math.max(delay - duration / 2, 0));\n\n setTimeout(cb, delay);\n } else {\n circle.classList.add('hiding');\n setTimeout(cb, duration / 2);\n }\n\n if(!IS_TOUCH_SUPPORTED) {\n window.removeEventListener('contextmenu', handler);\n window.removeEventListener('mousemove', handler);\n }\n\n handler = null;\n touchStartFired = false;\n };\n // });\n\n callback?.(clickId);\n\n /* callback().then((bad) => {\n if(bad) {\n span.remove();\n return;\n } */\n\n // console.log('ripple after promise', Date.now() - startTime);\n // console.log('ripple tooSlow:', tooSlow);\n /* if(tooSlow) {\n span.remove();\n return;\n } */\n\n fastRaf(() => {\n if(_handler !== handler) {\n return;\n }\n\n const rect = r.getBoundingClientRect();\n circle.classList.add('c-ripple__circle');\n\n const clickX = clientX - rect.left;\n const clickY = clientY - rect.top;\n\n const radius = Math.sqrt((Math.abs(clickY - rect.height / 2) + rect.height / 2) ** 2 + (Math.abs(clickX - rect.width / 2) + rect.width / 2) ** 2);\n const size = radius;\n\n // center of circle\n const x = clickX - size / 2;\n const y = clickY - size / 2;\n\n // console.log('ripple click', offsetFromCenter, size, clickX, clickY);\n\n circle.style.width = circle.style.height = size + 'px';\n circle.style.left = x + 'px';\n circle.style.top = y + 'px';\n\n // нижний код выполняется с задержкой\n /* animationEndPromise = new Promise((resolve) => {\n span.addEventListener('animationend', () => {\n // 713 -> 700\n resolve(((Date.now() - startTime) / 100 | 0) * 100);\n }, {once: true});\n }); */\n\n // нижний код не всегда включает анимацию ПРИ КЛИКЕ НА ТАЧПАД БЕЗ ТАПТИК ЭНЖИНА\n /* span.style.display = 'none';\n r.append(span);\n duration = +window.getComputedStyle(span).getPropertyValue('animation-duration').replace('s', '') * 1000;\n span.style.display = ''; */\n\n r.append(circle);\n\n if(auto) {\n // window.addEventListener('mousemove', handler, {once: true, passive: true});\n handler();\n }\n\n // r.classList.add('active');\n // handler();\n });\n // });\n };\n\n const isRippleUnneeded = (e: Event) => {\n return e.target !== elem && (\n ['BUTTON', 'A'].includes((e.target as HTMLElement).tagName) ||\n findUpClassName(e.target as HTMLElement, 'c-ripple') !== r\n ) && (\n attachListenerTo === elem ||\n !findUpAsChild(e.target as HTMLElement, attachListenerTo)\n ) && !findUpClassName(e.target, 'checkbox-field');\n };\n\n // TODO: rename this variable\n let touchStartFired = false;\n if(IS_TOUCH_SUPPORTED) {\n const touchEnd = () => {\n handler?.();\n };\n\n attachListenerTo.addEventListener('touchstart', (e) => {\n if(!liteMode.isAvailable('animations')) {\n return;\n }\n\n // console.log('ripple touchstart', e);\n if(e.touches.length > 1 || touchStartFired || isRippleUnneeded(e)) {\n return;\n }\n\n // console.log('touchstart', e);\n touchStartFired = true;\n\n const {clientX, clientY} = e.touches[0];\n drawRipple(clientX, clientY);\n attachListenerTo.addEventListener('touchend', touchEnd, {once: true});\n\n window.addEventListener('touchmove', (e) => {\n e.cancelBubble = true;\n e.stopPropagation();\n touchEnd();\n attachListenerTo.removeEventListener('touchend', touchEnd);\n }, {once: true});\n }, {passive: true});\n } else {\n attachListenerTo.addEventListener('mousedown', (e) => {\n if(![0, 2].includes(e.button)) { // only left and right buttons\n return;\n }\n\n if(!liteMode.isAvailable('animations')) {\n return;\n }\n // console.log('ripple mousedown', e, e.target, findUpClassName(e.target as HTMLElement, 'c-ripple') === r);\n\n if(attachListenerTo.dataset.ripple === '0' || isRippleUnneeded(e)) {\n return;\n } else if(touchStartFired) {\n touchStartFired = false;\n return;\n }\n\n const {clientX, clientY} = e;\n drawRipple(clientX, clientY);\n window.addEventListener('mouseup', handler, {once: true, passive: true});\n window.addEventListener('contextmenu', handler, {once: true, passive: true});\n }, {passive: true});\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport CheckboxField, {CheckboxFieldOptions} from './checkboxField';\nimport RadioField from './radioField';\nimport ripple from './ripple';\nimport {SliderSuperTab} from './slider';\nimport RadioForm from './radioForm';\nimport {i18n, LangPackKey} from '../lib/langPack';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport setInnerHTML, {setDirection} from '../helpers/dom/setInnerHTML';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport Button from './button';\nimport createContextMenu from '../helpers/dom/createContextMenu';\n\ntype K = string | HTMLElement | DocumentFragment | true;\n\nconst setContent = (element: HTMLElement, content: K) => {\n if(content === true) {\n\n } else if(typeof(content) === 'string') {\n setInnerHTML(element, content);\n } else {\n element.append(content);\n }\n};\n\nexport type RowMediaSizeType = 'small' | 'medium' | 'big' | 'abitbigger' | 'bigger';\n\nexport default class Row {\n public container: HTMLElement;\n public titleRow: HTMLElement;\n public titleRight: HTMLElement;\n public media: HTMLElement;\n\n public subtitleRow: HTMLElement;\n public subtitleRight: HTMLElement;\n\n public checkboxField: CheckboxField;\n public radioField: RadioField;\n\n public freezed = false;\n\n public buttonRight: HTMLElement;\n\n private _title: HTMLElement;\n private _subtitle: HTMLElement;\n private _midtitle: HTMLElement;\n\n constructor(options: Partial<{\n icon: string,\n subtitle: K,\n subtitleLangKey: LangPackKey,\n subtitleLangArgs: any[],\n subtitleRight: K,\n radioField: Row['radioField'],\n checkboxField: Row['checkboxField'],\n checkboxFieldOptions: CheckboxFieldOptions,\n withCheckboxSubtitle: boolean,\n title: K,\n titleLangKey: LangPackKey,\n titleRight: K,\n titleRightSecondary: K,\n clickable: boolean | ((e: Event) => void),\n navigationTab: SliderSuperTab,\n havePadding: boolean,\n noRipple: boolean,\n noWrap: boolean,\n listenerSetter: ListenerSetter,\n buttonRight?: HTMLElement | boolean,\n buttonRightLangKey: LangPackKey,\n asLink: boolean,\n contextMenu: Omit<Parameters<typeof createContextMenu>[0], 'findElement' | 'listenTo' | 'listenerSetter'>\n }> = {}) {\n if(options.checkboxFieldOptions) {\n options.checkboxField = new CheckboxField({\n listenerSetter: options.listenerSetter,\n ...options.checkboxFieldOptions\n });\n }\n\n const tagName = options.asLink ? 'a' : (options.radioField || options.checkboxField ? 'label' : 'div');\n this.container = document.createElement(tagName);\n this.container.classList.add('row', 'no-subtitle');\n\n if(options.noWrap) {\n this.container.classList.add('no-wrap');\n }\n\n if(options.subtitle) {\n const subtitle = this.subtitle;\n setContent(subtitle, options.subtitle);\n\n if(options.noWrap) subtitle.classList.add('no-wrap');\n\n if(options.subtitleRight) {\n this.container.append(this.subtitleRow = this.createRow());\n this.subtitleRow.classList.add('row-subtitle-row');\n const subtitleRight = this.subtitleRight = document.createElement('div');\n subtitleRight.classList.add('row-subtitle', 'row-subtitle-right');\n\n setContent(subtitleRight, options.subtitleRight);\n this.subtitleRow.append(subtitle, subtitleRight);\n }\n } else if(options.subtitleLangKey) {\n this.subtitle.append(i18n(options.subtitleLangKey, options.subtitleLangArgs));\n }\n\n let havePadding = !!options.havePadding;\n if(options.radioField || options.checkboxField) {\n if(options.radioField) {\n this.radioField = options.radioField;\n this.container.append(this.radioField.label);\n havePadding = true;\n }\n\n if(options.checkboxField) {\n this.checkboxField = options.checkboxField;\n\n const isToggle = options.checkboxField.label.classList.contains('checkbox-field-toggle');\n if(isToggle) {\n this.container.classList.add('row-with-toggle');\n options.titleRight = this.checkboxField.label;\n } else {\n havePadding = true;\n if(!this.checkboxField.span) {\n this.checkboxField.label.classList.add('checkbox-field-absolute');\n }\n this.container.append(this.checkboxField.label);\n }\n\n if(options.withCheckboxSubtitle && !isToggle) {\n const onChange = () => {\n replaceContent(this.subtitle, i18n(this.checkboxField.input.checked ? 'Checkbox.Enabled' : 'Checkbox.Disabled'));\n };\n\n if(options.listenerSetter) options.listenerSetter.add(this.checkboxField.input)('change', onChange);\n else this.checkboxField.input.addEventListener('change', onChange);\n }\n }\n\n const i = options.radioField || options.checkboxField;\n i.label.classList.add('disable-hover');\n }\n\n if(options.title || options.titleLangKey || options.titleRight || options.titleRightSecondary) {\n let c: HTMLElement;\n const titleRightContent = options.titleRight || options.titleRightSecondary;\n if(titleRightContent) {\n this.container.append(c = this.titleRow = this.createRow());\n this.titleRow.classList.add('row-title-row');\n } else {\n c = this.container;\n }\n\n this._title = this.createTitle();\n if(options.noWrap) this.title.classList.add('no-wrap');\n if(options.title) {\n setContent(this.title, options.title);\n } else if(options.titleLangKey) {\n this.title.append(i18n(options.titleLangKey));\n }\n\n c.append(this.title);\n\n if(titleRightContent) {\n const titleRight = this.titleRight = document.createElement('div');\n titleRight.classList.add('row-title', 'row-title-right');\n\n if(options.titleRightSecondary) {\n titleRight.classList.add('row-title-right-secondary');\n }\n\n setContent(titleRight, titleRightContent);\n c.append(titleRight);\n }\n }\n\n if(options.icon) {\n havePadding = true;\n // this.title.classList.add('tgico', 'tgico-' + options.icon);\n this.container.classList.add('tgico', 'tgico-' + options.icon);\n this.container.classList.add('row-with-icon');\n }\n\n if(havePadding) {\n this.container.classList.add('row-with-padding');\n }\n\n if(options.navigationTab) {\n options.clickable = () => options.navigationTab.open();\n }\n\n if(options.clickable || options.radioField || options.checkboxField) {\n if(typeof(options.clickable) === 'function') {\n attachClickEvent(this.container, (e) => {\n if(this.freezed) return;\n (options.clickable as any)(e);\n }, {listenerSetter: options.listenerSetter});\n }\n\n this.container.classList.add('row-clickable', 'hover-effect');\n\n if(!options.noRipple) {\n ripple(this.container, undefined, undefined, true);\n }\n\n /* if(options.radioField || options.checkboxField) {\n this.container.prepend(this.container.lastElementChild);\n } */\n }\n\n if(options.buttonRight || options.buttonRightLangKey) {\n this.buttonRight = options.buttonRight instanceof HTMLElement ?\n options.buttonRight :\n Button('btn-primary btn-color-primary', {text: options.buttonRightLangKey});\n this.container.append(this.buttonRight);\n }\n\n if(options.contextMenu) {\n createContextMenu({\n ...options.contextMenu,\n listenTo: this.container,\n listenerSetter: options.listenerSetter\n });\n }\n }\n\n public get title() {\n return this._title;\n }\n\n public get subtitle() {\n return this._subtitle ??= this.createSubtitle();\n }\n\n public get midtitle() {\n return this._midtitle ??= this.createMidtitle();\n }\n\n private createRow() {\n const c = document.createElement('div');\n c.classList.add('row-row');\n return c;\n }\n\n private createTitle() {\n const title = document.createElement('div');\n title.classList.add('row-title');\n setDirection(title);\n return title;\n }\n\n private createSubtitle() {\n const subtitle = document.createElement('div');\n subtitle.classList.add('row-subtitle');\n setDirection(subtitle);\n if(this.title) this.title.after(subtitle);\n else this.container.prepend(subtitle);\n this.container.classList.remove('no-subtitle');\n return subtitle;\n }\n\n private createMidtitle() {\n const midtitle = document.createElement('div');\n midtitle.classList.add('row-midtitle');\n this.subtitle.parentElement.insertBefore(midtitle, this.subtitle);\n return midtitle;\n }\n\n public createMedia(size?: RowMediaSizeType) {\n const media = document.createElement('div');\n return this.applyMediaElement(media, size);\n }\n\n public applyMediaElement(media: HTMLElement, size?: RowMediaSizeType) {\n this.container.classList.add('row-with-padding');\n\n this.media = media;\n media.classList.add('row-media');\n\n if(size) {\n media.classList.add('row-media-' + size);\n }\n\n this.container.append(media);\n\n return media;\n }\n\n public isDisabled() {\n return this.container.classList.contains('is-disabled');\n }\n\n public toggleDisability(disable = !this.container.classList.contains('is-disabled')) {\n this.container.classList.toggle('is-disabled', disable);\n return () => this.toggleDisability(!disable);\n }\n\n public disableWithPromise(promise: Promise<any>) {\n const toggle = this.toggleDisability(true);\n promise.finally(() => {\n toggle();\n });\n }\n\n public makeSortable() {\n const sortIcon = document.createElement('span');\n this.container.classList.add('row-sortable', 'tgico');\n sortIcon.classList.add('row-sortable-icon', 'tgico-menu');\n this.container.append(sortIcon);\n }\n\n public toggleSorting(enabled?: boolean) {\n this.container.classList.toggle('cant-sort', !enabled);\n }\n}\n\nexport const CreateRowFromCheckboxField = (checkboxField: CheckboxField) => {\n return new Row({checkboxField, listenerSetter: checkboxField.listenerSetter});\n};\n\nexport const RadioFormFromRows = (rows: Row[], onChange: (value: string) => void) => {\n return RadioForm(rows.map((r) => ({container: r.container, input: r.radioField.input})), onChange);\n};\n\nexport const RadioFormFromValues = (values: {langPackKey: LangPackKey, value: number | string, checked?: boolean}[], onChange: Parameters<typeof RadioFormFromRows>[1]) => {\n const name = 'name-' + (Math.random() * 0x7FFFFF | 0);\n let checkedRadioField: RadioField;\n const rows = values.map(({langPackKey, value, checked}) => {\n const row = new Row({\n radioField: new RadioField({\n langKey: langPackKey,\n name,\n value: '' + value\n })\n });\n\n if(checked) {\n checkedRadioField = row.radioField;\n }\n\n return row;\n });\n\n const form = RadioFormFromRows(rows, onChange);\n if(checkedRadioField) {\n checkedRadioField.checked = true;\n }\n return form;\n};\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport {logger, LogTypes} from '../lib/logger';\nimport fastSmoothScroll, {ScrollOptions} from '../helpers/fastSmoothScroll';\nimport useHeavyAnimationCheck from '../hooks/useHeavyAnimationCheck';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {IS_ANDROID} from '../environment/userAgent';\n/*\nvar el = $0;\nvar height = 0;\nvar checkUp = false;\n\ndo {\n height += el.scrollHeight;\n} while(el = (checkUp ? el.previousElementSibling : el.nextElementSibling));\nconsole.log(height);\n*/\n\n/*\nArray.from($0.querySelectorAll('.bubble-content')).forEach((_el) => {\n //_el.style.display = '';\n //return;\n\n let el = _el.parentElement;\n let height = el.scrollHeight;\n let width = el.scrollWidth;\n el.style.width = width + 'px';\n el.style.height = height + 'px';\n _el.style.display = 'none';\n});\n*/\n\n/* const scrollables: Map<HTMLElement, Scrollable> = new Map();\nconst scrollsIntersector = new IntersectionObserver((entries) => {\n for(let entry of entries) {\n const scrollable = scrollables.get(entry.target as HTMLElement);\n\n if(entry.isIntersecting) {\n scrollable.isVisible = true;\n } else {\n scrollable.isVisible = false;\n\n if(!isInDOM(entry.target)) {\n scrollsIntersector.unobserve(scrollable.container);\n scrollables.delete(scrollable.container);\n }\n }\n }\n}); */\n\nconst SCROLL_THROTTLE = /* IS_ANDROID ? 200 : */24;\n\nexport class ScrollableBase {\n protected log: ReturnType<typeof logger>;\n\n public splitUp: HTMLElement;\n public onScrollMeasure: number = 0;\n\n public lastScrollPosition: number = 0;\n public lastScrollDirection: number = 0;\n\n public onAdditionalScroll: () => void;\n public onScrolledTop: () => void;\n public onScrolledBottom: () => void;\n\n public isHeavyAnimationInProgress = false;\n protected needCheckAfterAnimation = false;\n\n public checkForTriggers?: () => void;\n\n public scrollProperty: 'scrollTop' | 'scrollLeft';\n\n protected removeHeavyAnimationListener: () => void;\n protected addedScrollListener: boolean;\n\n constructor(public el?: HTMLElement, logPrefix = '', public container: HTMLElement = document.createElement('div')) {\n this.container.classList.add('scrollable');\n\n this.log = logger('SCROLL' + (logPrefix ? '-' + logPrefix : ''), LogTypes.Error);\n\n if(el) {\n Array.from(el.children).forEach((c) => this.container.append(c));\n\n el.append(this.container);\n }\n // this.onScroll();\n }\n\n public addScrollListener() {\n if(this.addedScrollListener) {\n return;\n }\n\n this.addedScrollListener = true;\n this.container.addEventListener('scroll', this.onScroll, {passive: true, capture: true});\n }\n\n public removeScrollListener() {\n if(!this.addedScrollListener) {\n return;\n }\n\n this.addedScrollListener = false;\n this.container.removeEventListener('scroll', this.onScroll, {capture: true});\n }\n\n public setListeners() {\n if(this.removeHeavyAnimationListener) {\n return;\n }\n\n window.addEventListener('resize', this.onScroll, {passive: true});\n this.addScrollListener();\n\n this.removeHeavyAnimationListener = useHeavyAnimationCheck(() => {\n this.isHeavyAnimationInProgress = true;\n\n if(this.onScrollMeasure) {\n this.cancelMeasure();\n this.needCheckAfterAnimation = true;\n }\n }, () => {\n this.isHeavyAnimationInProgress = false;\n\n if(this.needCheckAfterAnimation) {\n this.onScroll();\n this.needCheckAfterAnimation = false;\n }\n });\n }\n\n public removeListeners() {\n if(!this.removeHeavyAnimationListener) {\n return;\n }\n\n window.removeEventListener('resize', this.onScroll);\n this.removeScrollListener();\n\n this.removeHeavyAnimationListener();\n this.removeHeavyAnimationListener = undefined;\n }\n\n public destroy() {\n this.removeListeners();\n this.onAdditionalScroll = undefined;\n this.onScrolledTop = undefined;\n this.onScrolledBottom = undefined;\n }\n\n public append(...args: Parameters<HTMLElement['append']>) {\n this.container.append(...args);\n }\n\n public scrollIntoViewNew(options: Omit<ScrollOptions, 'container'>) {\n // return Promise.resolve();\n // this.removeListeners();\n return fastSmoothScroll({\n ...options,\n container: this.container\n });/* .finally(() => {\n this.setListeners();\n }); */\n }\n\n public onScroll = () => {\n // if(this.debug) {\n // this.log('onScroll call', this.onScrollMeasure);\n // }\n\n // return;\n\n if(this.isHeavyAnimationInProgress) {\n this.cancelMeasure();\n this.needCheckAfterAnimation = true;\n return;\n }\n\n // if(this.onScrollMeasure || ((this.scrollLocked || (!this.onScrolledTop && !this.onScrolledBottom)) && !this.splitUp && !this.onAdditionalScroll)) return;\n if((!this.onScrolledTop && !this.onScrolledBottom) && !this.splitUp && !this.onAdditionalScroll) return;\n if(this.onScrollMeasure) return;\n // if(this.onScrollMeasure) window.cancelAnimationFrame(this.onScrollMeasure);\n // this.onScrollMeasure = window.requestAnimationFrame(() => {\n this.onScrollMeasure = window.setTimeout(() => {\n this.onScrollMeasure = 0;\n\n const scrollPosition = this.container[this.scrollProperty];\n this.lastScrollDirection = this.lastScrollPosition === scrollPosition ? 0 : (this.lastScrollPosition < scrollPosition ? 1 : -1); // * 1 - bottom, -1 - top\n this.lastScrollPosition = scrollPosition;\n\n // lastScrollDirection check is useless here, every callback should decide on its own\n if(this.onAdditionalScroll/* && this.lastScrollDirection !== 0 */) {\n this.onAdditionalScroll();\n }\n\n if(this.checkForTriggers) {\n this.checkForTriggers();\n }\n // });\n }, SCROLL_THROTTLE);\n };\n\n public cancelMeasure() {\n if(this.onScrollMeasure) {\n // window.cancelAnimationFrame(this.onScrollMeasure);\n clearTimeout(this.onScrollMeasure);\n this.onScrollMeasure = 0;\n }\n }\n}\n\nexport type SliceSides = 'top' | 'bottom';\nexport type SliceSidesContainer = {[k in SliceSides]: boolean};\n\nexport default class Scrollable extends ScrollableBase {\n public padding: HTMLElement;\n\n public loadedAll: SliceSidesContainer = {top: true, bottom: false};\n\n constructor(el?: HTMLElement, logPrefix = '', public onScrollOffset = 300, withPaddingContainer?: boolean) {\n super(el, logPrefix);\n\n /* if(withPaddingContainer) {\n this.padding = document.createElement('div');\n this.padding.classList.add('scrollable-padding');\n Array.from(this.container.children).forEach((c) => this.padding.append(c));\n this.container.append(this.padding);\n } */\n\n this.container.classList.add('scrollable-y');\n this.setListeners();\n this.scrollProperty = 'scrollTop';\n }\n\n public attachBorderListeners(setClassOn = this.container) {\n const cb = this.onAdditionalScroll;\n this.onAdditionalScroll = () => {\n cb?.();\n setClassOn.classList.toggle('scrolled-top', !this.scrollTop);\n setClassOn.classList.toggle('scrolled-bottom', this.isScrolledDown);\n };\n\n setClassOn.classList.add('scrolled-top', 'scrolled-bottom', 'scrollable-y-bordered');\n }\n\n public setVirtualContainer(el?: HTMLElement) {\n this.splitUp = el;\n this.log('setVirtualContainer:', el, this);\n }\n\n public checkForTriggers = () => {\n if((!this.onScrolledTop && !this.onScrolledBottom)) return;\n\n if(this.isHeavyAnimationInProgress) {\n this.onScroll();\n return;\n }\n\n const scrollHeight = this.container.scrollHeight;\n if(!scrollHeight) { // незачем вызывать триггеры если блок пустой или не виден\n return;\n }\n\n const clientHeight = this.container.clientHeight;\n const maxScrollTop = scrollHeight - clientHeight;\n const scrollTop = this.lastScrollPosition;\n\n // this.log('checkForTriggers:', scrollTop, maxScrollTop);\n\n if(this.onScrolledTop && scrollTop <= this.onScrollOffset && this.lastScrollDirection <= 0/* && direction === -1 */) {\n this.onScrolledTop();\n }\n\n if(this.onScrolledBottom && (maxScrollTop - scrollTop) <= this.onScrollOffset && this.lastScrollDirection >= 0/* && direction === 1 */) {\n this.onScrolledBottom();\n }\n };\n\n public prepend(...elements: (HTMLElement | DocumentFragment)[]) {\n (this.splitUp || this.padding || this.container).prepend(...elements);\n }\n\n public append(...elements: (HTMLElement | DocumentFragment)[]) {\n (this.splitUp || this.padding || this.container).append(...elements);\n }\n\n public getDistanceToEnd() {\n return this.scrollHeight - Math.round(this.scrollTop + this.container.offsetHeight);\n }\n\n get isScrolledDown() {\n return this.getDistanceToEnd() <= 1;\n }\n\n set scrollTop(y: number) {\n this.container.scrollTop = y;\n }\n\n get scrollTop() {\n // this.log.trace('get scrollTop');\n return this.container.scrollTop;\n }\n\n public setScrollTopSilently(value: number) {\n this.lastScrollPosition = value;\n this.ignoreNextScrollEvent();\n\n this.scrollTop = value;\n }\n\n public ignoreNextScrollEvent() {\n if(this.removeHeavyAnimationListener) {\n this.removeScrollListener();\n this.container.addEventListener('scroll', (e) => {\n cancelEvent(e);\n this.addScrollListener();\n }, {capture: true, passive: false, once: true});\n }\n }\n\n get scrollHeight() {\n return this.container.scrollHeight;\n }\n}\n\nexport class ScrollableX extends ScrollableBase {\n constructor(el: HTMLElement, logPrefix = '', public onScrollOffset = 300, public splitCount = 15, public container: HTMLElement = document.createElement('div')) {\n super(el, logPrefix, container);\n\n this.container.classList.add('scrollable-x');\n\n if(!IS_TOUCH_SUPPORTED) {\n const scrollHorizontally = (e: any) => {\n if(!e.deltaX && this.container.scrollWidth > this.container.clientWidth) {\n this.container.scrollLeft += e.deltaY / 4;\n cancelEvent(e);\n }\n };\n\n this.container.addEventListener('wheel', scrollHorizontally, {passive: false});\n }\n\n this.scrollProperty = 'scrollLeft';\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {LangPackKey, FormatterArguments, i18n_} from '../lib/langPack';\nimport {generateDelimiter} from './generateDelimiter';\nimport Scrollable from './scrollable';\n\nexport type SettingSectionOptions = {\n name?: LangPackKey,\n nameArgs?: FormatterArguments,\n caption?: LangPackKey | true,\n captionArgs?: FormatterArguments,\n captionOld?: SettingSectionOptions['caption'],\n noDelimiter?: boolean,\n fakeGradientDelimiter?: boolean,\n noShadow?: boolean,\n // fullWidth?: boolean,\n // noPaddingTop?: boolean\n};\n\nconst className = 'sidebar-left-section';\nexport default class SettingSection {\n public container: HTMLElement;\n public innerContainer: HTMLElement;\n public content: HTMLElement;\n public title: HTMLElement;\n public caption: HTMLElement;\n\n private fullWidth: boolean;\n\n constructor(options: SettingSectionOptions = {}) {\n const container = this.container = document.createElement('div');\n container.classList.add(className + '-container');\n\n const innerContainer = this.innerContainer = document.createElement('div');\n innerContainer.classList.add(className);\n\n if(options.noShadow) {\n innerContainer.classList.add('no-shadow');\n }\n\n if(options.fakeGradientDelimiter) {\n innerContainer.append(generateDelimiter());\n innerContainer.classList.add('with-fake-delimiter');\n } else if(!options.noDelimiter) {\n const hr = document.createElement('hr');\n innerContainer.append(hr);\n } else {\n innerContainer.classList.add('no-delimiter');\n }\n\n // if(options.fullWidth) {\n // this.fullWidth = true;\n // }\n\n // if(options.noPaddingTop) {\n // innerContainer.classList.add('no-padding-top');\n // }\n\n const content = this.content = this.generateContentElement();\n\n if(options.name) {\n const title = this.title = document.createElement('div');\n title.classList.add('sidebar-left-h2', className + '-name');\n i18n_({element: title, key: options.name, args: options.nameArgs});\n content.append(title);\n }\n\n container.append(innerContainer);\n\n const caption = options.caption ?? options.captionOld;\n if(caption) {\n const el = this.caption = this.generateContentElement();\n el.classList.add(className + '-caption');\n\n if(!options.captionOld) {\n container.append(el);\n }\n\n if(caption !== true) {\n i18n_({element: el, key: caption, args: options.captionArgs});\n }\n }\n }\n\n public generateContentElement() {\n const content = document.createElement('div');\n content.classList.add(className + '-content');\n\n // if(this.fullWidth) {\n // content.classList.add('full-width');\n // }\n\n this.innerContainer.append(content);\n return content;\n }\n}\n\nexport const generateSection = (appendTo: Scrollable, name?: LangPackKey, caption?: LangPackKey) => {\n const section = new SettingSection({name, caption});\n appendTo.append(section.container);\n return section.content;\n};\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {InputFile} from '../../../layer';\nimport appDialogsManager from '../../../lib/appManagers/appDialogsManager';\nimport InputField from '../../inputField';\nimport {SliderSuperTab} from '../../slider';\nimport AvatarEdit from '../../avatarEdit';\nimport I18n, {joinElementsWith} from '../../../lib/langPack';\nimport ButtonCorner from '../../buttonCorner';\nimport getUserStatusString from '../../wrappers/getUserStatusString';\nimport appImManager from '../../../lib/appManagers/appImManager';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport SettingSection from '../../settingSection';\n\ninterface OpenStreetMapInterface {\n place_id?: number;\n license?: string;\n osm_type?: string;\n osm_id?: number;\n lat?: string;\n lon?: string;\n display_name: string;\n address?: object;\n boundingbox?: object;\n}\n\nexport default class AppNewGroupTab extends SliderSuperTab {\n private avatarEdit: AvatarEdit;\n private uploadAvatar: () => Promise<InputFile> = null;\n private peerIds: PeerId[];\n private isGeoChat: boolean = false;\n private nextBtn: HTMLButtonElement;\n private groupNameInputField: InputField;\n private list: HTMLUListElement;\n private groupLocationInputField: InputField;\n private userLocationCoords: {lat: number, long: number};\n private userLocationAddress: string;\n\n public init(\n peerIds: PeerId[],\n isGeoChat: boolean = false\n ) {\n this.isGeoChat = isGeoChat;\n this.peerIds = peerIds;\n\n this.container.classList.add('new-group-container');\n this.setTitle('NewGroup');\n\n this.avatarEdit = new AvatarEdit((_upload) => {\n this.uploadAvatar = _upload;\n });\n\n const section = new SettingSection({});\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n this.groupNameInputField = new InputField({\n label: 'CreateGroup.NameHolder',\n maxLength: 128\n });\n\n this.groupLocationInputField = new InputField({\n label: 'ChatLocation',\n name: 'location',\n canBeEdited: false\n });\n\n inputWrapper.append(\n this.groupNameInputField.container,\n this.groupLocationInputField.container\n );\n\n this.listenerSetter.add(this.groupNameInputField.input)('input', () => {\n const value = this.groupNameInputField.value;\n let valueCheck = !!value.length && !this.groupNameInputField.input.classList.contains('error');\n if(this.isGeoChat) valueCheck = valueCheck && !!this.userLocationCoords && !!this.userLocationAddress;\n this.nextBtn.classList.toggle('is-visible', !!valueCheck);\n });\n\n this.nextBtn = ButtonCorner({icon: 'arrow_next'});\n\n attachClickEvent(this.nextBtn, () => {\n const title = this.groupNameInputField.value;\n\n let promise: Promise<ChatId>;\n if(this.isGeoChat) {\n if(!this.userLocationAddress || !this.userLocationCoords) return;\n promise = this.managers.appChatsManager.createChannel({\n title,\n about: '',\n geo_point: {\n _: 'inputGeoPoint',\n ...this.userLocationCoords\n },\n address: this.userLocationAddress,\n megagroup: true\n }).then((chatId) => {\n if(this.uploadAvatar) {\n this.uploadAvatar().then((inputFile) => {\n this.managers.appChatsManager.editPhoto(chatId, inputFile);\n });\n }\n\n if(this.peerIds.length) {\n this.managers.appChatsManager.inviteToChannel(chatId, this.peerIds);\n }\n\n return chatId;\n });\n } else {\n this.nextBtn.disabled = true;\n promise = this.managers.appChatsManager.createChat(title, this.peerIds.map((peerId) => peerId.toUserId())).then((chatId) => {\n if(this.uploadAvatar) {\n this.uploadAvatar().then((inputFile) => {\n this.managers.appChatsManager.editPhoto(chatId, inputFile);\n });\n }\n\n return chatId;\n });\n }\n\n if(!promise) {\n return;\n }\n\n promise.then((chatId) => {\n this.close();\n\n appImManager.setInnerPeer({peerId: chatId.toPeerId(true)});\n });\n }, {listenerSetter: this.listenerSetter});\n\n const chatsSection = new SettingSection({\n name: 'Members',\n nameArgs: [this.peerIds.length]\n });\n\n if(!this.peerIds.length) {\n chatsSection.container.classList.add('hide');\n }\n\n const list = this.list = appDialogsManager.createChatList({\n new: true\n });\n\n chatsSection.content.append(list);\n\n section.content.append(this.avatarEdit.container, inputWrapper);\n\n this.content.append(this.nextBtn);\n this.scrollable.append(section.container, chatsSection.container);\n\n if(isGeoChat) {\n this.setTitle('NearbyCreateGroup');\n this.groupLocationInputField.container.classList.remove('hide');\n this.groupLocationInputField.setValueSilently(I18n.format('Loading', true));\n this.startLocating();\n } else {\n this.groupLocationInputField.container.classList.add('hide');\n }\n\n const usersPromise = Promise.all(this.peerIds.map((peerId) => this.managers.appUsersManager.getUser(peerId.toUserId())));\n const myUserPromise = this.managers.appUsersManager.getSelf();\n\n const a = usersPromise.then((users) => {\n return users.map((user) => {\n const {dom} = appDialogsManager.addDialogNew({\n peerId: user.id.toPeerId(false),\n container: this.list,\n rippleEnabled: false,\n avatarSize: 'abitbigger'\n });\n\n dom.lastMessageSpan.append(getUserStatusString(user));\n })\n });\n\n const setTitlePromise = this.peerIds.length > 0 && this.peerIds.length < 5 ? Promise.all([usersPromise, myUserPromise]).then(([users, myUser]) => {\n const names = users.map((user) => [user.first_name, user.last_name].filter(Boolean).join(' '));\n names.unshift(myUser.first_name);\n\n const joined = joinElementsWith(names, (isLast) => isLast ? ', ' : ' & ').join('');\n this.groupNameInputField.setDraftValue(joined);\n }) : Promise.resolve();\n\n return Promise.all([\n a,\n setTitlePromise\n ]);\n }\n\n public onCloseAfterTimeout() {\n this.avatarEdit.clear();\n this.uploadAvatar = null;\n this.groupNameInputField.value = '';\n this.groupLocationInputField.container.classList.add('hide');\n this.nextBtn.disabled = false;\n }\n\n private startLocating() {\n navigator.geolocation.getCurrentPosition((location) => {\n this.userLocationCoords = {\n lat: location.coords.latitude,\n long: location.coords.longitude\n };\n\n let uri = 'https://nominatim.openstreetmap.org/reverse';\n uri += '?lat='+location.coords.latitude;\n uri += '&lon='+location.coords.longitude;\n uri += '&format=json';\n uri += '&addressdetails=1';\n uri += '&accept-language=en';\n fetch(uri)\n .then((response) => response.json())\n .then((response: OpenStreetMapInterface) => {\n this.userLocationAddress = response.display_name;\n this.groupLocationInputField.setValueSilently(response.display_name);\n });\n }, (error) => {\n if(error instanceof GeolocationPositionError) {\n this.groupLocationInputField.setValueSilently('Location permission denied. Please retry later.');\n } else {\n this.groupLocationInputField.setValueSilently('An error has occurred. Please retry later.');\n }\n });\n }\n}\n","enum PrivacyType {\n Everybody = 2,\n Contacts = 1,\n Nobody = 0\n}\n\nexport default PrivacyType;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {PrivacyRule} from '../../../../layer';\nimport PrivacyType from './privacyType';\n\nexport default function getPrivacyRulesDetails(rules: PrivacyRule[]) {\n const types: PrivacyType[] = [];\n\n type peers = {users: UserId[], chats: ChatId[]};\n const allowPeers: peers = {users: [], chats: []}, disallowPeers: peers = {users: [], chats: []};\n rules.forEach((rule) => {\n switch(rule._) {\n case 'privacyValueAllowAll':\n types.push(2);\n break;\n case 'privacyValueDisallowAll':\n types.push(0);\n break;\n case 'privacyValueAllowContacts':\n types.push(1);\n break;\n /* case 'privacyValueDisallowContacts':\n types.push('Except My Contacts');\n break; */\n case 'privacyValueAllowChatParticipants':\n allowPeers.chats.push(...rule.chats);\n break;\n case 'privacyValueAllowUsers':\n allowPeers.users.push(...rule.users);\n break;\n case 'privacyValueDisallowChatParticipants':\n disallowPeers.chats.push(...rule.chats);\n break;\n case 'privacyValueDisallowUsers':\n disallowPeers.users.push(...rule.users);\n break;\n }\n });\n\n return {type: types[0], disallowPeers, allowPeers};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport replaceContent from '../helpers/dom/replaceContent';\nimport {randomLong} from '../helpers/random';\nimport {InputPrivacyKey, InputPrivacyRule} from '../layer';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport getPrivacyRulesDetails from '../lib/appManagers/utils/privacy/getPrivacyRulesDetails';\nimport PrivacyType from '../lib/appManagers/utils/privacy/privacyType';\nimport {i18n, join, LangPackKey, _i18n} from '../lib/langPack';\nimport RadioField from './radioField';\nimport Row, {RadioFormFromRows} from './row';\nimport Scrollable from './scrollable';\nimport SettingSection, {generateSection} from './settingSection';\nimport AppAddMembersTab from './sidebarLeft/tabs/addMembers';\nimport {SliderSuperTabEventable} from './sliderTab';\n\nexport type PrivacySectionStr = LangPackKey | '' | HTMLElement;\nexport default class PrivacySection {\n public radioRows: Map<PrivacyType, Row>;\n public radioSection: SettingSection;\n public exceptions: Map<keyof PrivacySection['peerIds'], {\n titleLangKey: LangPackKey,\n key: keyof PrivacySection['peerIds'],\n row: Row,\n icon: string,\n subtitleLangKey: LangPackKey,\n clickable: true\n }>;\n public peerIds: {\n disallow?: PeerId[],\n allow?: PeerId[]\n };\n public type: PrivacyType;\n\n constructor(public options: {\n tab: SliderSuperTabEventable,\n title: LangPackKey,\n inputKey: InputPrivacyKey['_'],\n captions?: [PrivacySectionStr, PrivacySectionStr, PrivacySectionStr],\n appendTo?: Scrollable,\n noExceptions?: boolean,\n onRadioChange?: (value: number) => any,\n skipTypes?: PrivacyType[],\n exceptionTexts?: [LangPackKey, LangPackKey],\n managers: AppManagers\n }) {\n if(options.captions) {\n options.captions.reverse();\n }\n\n const managers = options.managers;\n\n this.radioSection = new SettingSection({name: options.title, caption: true});\n\n this.radioRows = new Map();\n\n let r: Array<{type: PrivacyType, langKey: LangPackKey}> = [{\n type: PrivacyType.Everybody,\n langKey: 'PrivacySettingsController.Everbody'\n }, {\n type: PrivacyType.Contacts,\n langKey: 'PrivacySettingsController.MyContacts'\n }, {\n type: PrivacyType.Nobody,\n langKey: 'PrivacySettingsController.Nobody'\n }];\n\n if(options.skipTypes) {\n r = r.filter((r) => !options.skipTypes.includes(r.type));\n }\n\n const random = randomLong();\n r.forEach(({type, langKey}) => {\n const row = new Row({\n radioField: new RadioField({\n langKey,\n name: random,\n value: '' + type\n })\n });\n\n this.radioRows.set(type, row);\n });\n\n const form = RadioFormFromRows([...this.radioRows.values()], this.onRadioChange);\n\n this.radioSection.content.append(form);\n if(options.appendTo) {\n options.appendTo.append(this.radioSection.container);\n }\n\n if(!options.noExceptions) {\n const container = generateSection(options.appendTo, 'PrivacyExceptions', 'PrivacySettingsController.PeerInfo');\n\n this.exceptions = new Map([[\n 'disallow',\n {\n titleLangKey: options.exceptionTexts[0],\n key: 'disallow',\n row: null,\n icon: 'deleteuser',\n subtitleLangKey: 'PrivacySettingsController.AddUsers',\n clickable: true\n }\n ], [\n 'allow',\n {\n titleLangKey: options.exceptionTexts[1],\n key: 'allow',\n row: null,\n icon: 'adduser',\n subtitleLangKey: 'PrivacySettingsController.AddUsers',\n clickable: true\n }\n ]]);\n\n this.exceptions.forEach((exception) => {\n exception.row = new Row(exception);\n\n exception.row.container.addEventListener('click', () => {\n promise.then(() => {\n const _peerIds = this.peerIds[exception.key];\n options.tab.slider.createTab(AppAddMembersTab).open({\n type: 'privacy',\n skippable: true,\n title: exception.titleLangKey,\n placeholder: 'PrivacyModal.Search.Placeholder',\n takeOut: (newPeerIds) => {\n _peerIds.length = 0;\n _peerIds.push(...newPeerIds);\n exception.row.subtitle.replaceChildren(...this.generateStr(this.splitPeersByType(newPeerIds)));\n },\n selectedPeerIds: _peerIds\n });\n });\n });\n\n container.append(exception.row.container);\n });\n }\n\n /* setTimeout(() => {\n this.setRadio(PrivacyType.Contacts);\n }, 0); */\n\n const promise = managers.appPrivacyManager.getPrivacy(options.inputKey).then((rules) => {\n const details = getPrivacyRulesDetails(rules);\n this.setRadio(details.type);\n\n if(this.exceptions) {\n this.peerIds = {};\n ['allow' as const, 'disallow' as const].forEach((k) => {\n const arr = [];\n const from = k === 'allow' ? details.allowPeers : details.disallowPeers;\n arr.push(...from.users.map((id) => id.toPeerId()));\n arr.push(...from.chats.map((id) => id.toPeerId(true)));\n this.peerIds[k] = arr;\n const s = this.exceptions.get(k).row.subtitle;\n s.replaceChildren();\n s.append(...this.generateStr(from));\n });\n }\n\n options.tab.eventListener.addEventListener('destroy', async() => {\n const rules: InputPrivacyRule[] = [];\n\n switch(this.type) {\n case PrivacyType.Everybody:\n rules.push({_: 'inputPrivacyValueAllowAll'});\n break;\n case PrivacyType.Contacts:\n rules.push({_: 'inputPrivacyValueAllowContacts'});\n break;\n case PrivacyType.Nobody:\n rules.push({_: 'inputPrivacyValueDisallowAll'});\n break;\n }\n\n if(this.exceptions) {\n const a = ([\n ['allow', 'inputPrivacyValueAllowChatParticipants', 'inputPrivacyValueAllowUsers'],\n ['disallow', 'inputPrivacyValueDisallowChatParticipants', 'inputPrivacyValueDisallowUsers']\n ] as Array<[\n 'allow' | 'disallow',\n 'inputPrivacyValueAllowChatParticipants' | 'inputPrivacyValueDisallowChatParticipants',\n 'inputPrivacyValueAllowUsers' | 'inputPrivacyValueDisallowUsers'\n ]>);\n for(const [k, chatKey, usersKey] of a) {\n if(this.exceptions.get(k).row.container.classList.contains('hide')) {\n continue;\n }\n\n const _peerIds = this.peerIds[k];\n if(_peerIds) {\n const splitted = this.splitPeersByType(_peerIds);\n if(splitted.chats.length) {\n rules.push({_: chatKey, chats: splitted.chats});\n }\n\n if(splitted.users.length) {\n rules.push({\n _: usersKey,\n users: await Promise.all(splitted.users.map((id) => managers.appUsersManager.getUserInput(id)))\n });\n }\n }\n }\n }\n\n managers.appPrivacyManager.setPrivacy(options.inputKey, rules);\n }, {once: true});\n });\n }\n\n private onRadioChange = (value: string | PrivacySection['type']) => {\n value = +value as PrivacySection['type'];\n this.type = value;\n\n const caption = this.options.captions[this.type];\n const captionElement = this.radioSection.caption;\n if(!caption) {\n captionElement.replaceChildren();\n } else if(caption instanceof HTMLElement) {\n replaceContent(captionElement, caption);\n } else {\n _i18n(captionElement, caption);\n }\n captionElement.classList.toggle('hide', !caption);\n\n if(this.exceptions) {\n this.exceptions.get('allow').row.container.classList.toggle('hide', this.type === PrivacyType.Everybody);\n this.exceptions.get('disallow').row.container.classList.toggle('hide', this.type === PrivacyType.Nobody);\n }\n\n this.options.onRadioChange && this.options.onRadioChange(value);\n };\n\n public setRadio(type: PrivacySection['type']) {\n const row = this.radioRows.get(type);\n this.onRadioChange(type);\n row.radioField.input.checked = true;\n }\n\n private splitPeersByType(peerIds: PeerId[]) {\n const peers = {users: [] as UserId[], chats: [] as ChatId[]};\n peerIds.forEach((peerId) => {\n peers[peerId.isAnyChat() ? 'chats' : 'users'].push(peerId.isAnyChat() ? peerId.toChatId() : peerId);\n });\n\n return peers;\n }\n\n private generateStr(peers: {users: UserId[], chats: ChatId[]}) {\n if(!peers.users.length && !peers.chats.length) {\n return [i18n('PrivacySettingsController.AddUsers')];\n }\n\n return join([\n peers.users.length ? i18n('Users', [peers.users.length]) : null,\n peers.chats.length ? i18n('Chats', [peers.chats.length]) : null\n ].filter(Boolean), false);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTabEventable} from '../../../sliderTab';\nimport PrivacySection from '../../../privacySection';\nimport {i18n, LangPackKey} from '../../../../lib/langPack';\nimport anchorCopy from '../../../../helpers/dom/anchorCopy';\nimport PrivacyType from '../../../../lib/appManagers/utils/privacy/privacyType';\n\nexport default class AppPrivacyPhoneNumberTab extends SliderSuperTabEventable {\n public async init() {\n this.container.classList.add('privacy-tab', 'privacy-phone-number');\n this.setTitle('PrivacyPhone');\n\n const formatted = '+' + (await this.managers.appUsersManager.getSelf()).phone;\n const captionEl = document.createElement('div');\n captionEl.append(\n i18n('PrivacyPhoneInfo'),\n document.createElement('br'),\n document.createElement('br'),\n i18n('PrivacyPhoneInfo4'),\n document.createElement('br'),\n anchorCopy({\n mePath: formatted\n })\n );\n\n const phoneSection = new PrivacySection({\n tab: this,\n title: 'PrivacyPhoneTitle',\n inputKey: 'inputPrivacyKeyPhoneNumber',\n captions: [captionEl, captionEl, ''],\n exceptionTexts: ['PrivacySettingsController.NeverShare', 'PrivacySettingsController.AlwaysShare'],\n appendTo: this.scrollable,\n onRadioChange: (type) => {\n s.setRadio(PrivacyType.Everybody);\n s.radioSection.container.classList.toggle('hide', type !== PrivacyType.Nobody);\n },\n managers: this.managers\n });\n\n const sCaption: LangPackKey = 'PrivacyPhoneInfo3';\n const s = new PrivacySection({\n tab: this,\n title: 'PrivacyPhoneTitle2',\n inputKey: 'inputPrivacyKeyAddedByPhone',\n captions: [sCaption, sCaption, ''],\n noExceptions: true,\n skipTypes: [PrivacyType.Nobody],\n managers: this.managers\n });\n\n this.scrollable.container.insertBefore(s.radioSection.container, phoneSection.radioSection.container.nextSibling);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {attachClickEvent} from '../../../../helpers/dom/clickEvent';\nimport Button from '../../../button';\nimport SettingSection from '../../../settingSection';\nimport {SliderSuperTab} from '../../../slider';\nimport wrapStickerEmoji from '../../../wrappers/stickerEmoji';\nimport AppSettingsTab from '../settings';\n\nexport default class AppTwoStepVerificationSetTab extends SliderSuperTab {\n public init() {\n this.container.classList.add('two-step-verification', 'two-step-verification-set');\n this.setTitle('TwoStepVerificationPasswordSet');\n\n const section = new SettingSection({\n captionOld: 'TwoStepVerificationPasswordSetInfo',\n noDelimiter: true\n });\n\n const emoji = '🥳';\n const stickerContainer = document.createElement('div');\n\n wrapStickerEmoji({\n emoji,\n div: stickerContainer,\n width: 160,\n height: 160\n });\n\n section.content.append(stickerContainer);\n\n const inputContent = section.generateContentElement();\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n const btnReturn = Button('btn-primary btn-color-primary', {text: 'TwoStepVerificationPasswordReturnSettings'});\n\n attachClickEvent(btnReturn, (e) => {\n this.close();\n });\n\n this.slider.sliceTabsUntilTab(AppSettingsTab, this);\n\n inputWrapper.append(btnReturn);\n\n inputContent.append(inputWrapper);\n\n this.scrollable.container.append(section.container);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {IS_MOBILE_SAFARI} from '../../environment/userAgent';\n\nexport function canFocus(isFirstInput: boolean) {\n return !IS_MOBILE_SAFARI || !isFirstInput;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AccountPassword} from '../../../../layer';\nimport Button from '../../../button';\nimport {SliderSuperTab} from '../../../slider';\nimport AppTwoStepVerificationSetTab from './passwordSet';\nimport CodeInputField from '../../../codeInputField';\nimport AppTwoStepVerificationEmailTab from './email';\nimport {putPreloader} from '../../../putPreloader';\nimport {i18n, _i18n} from '../../../../lib/langPack';\nimport {canFocus} from '../../../../helpers/dom/canFocus';\nimport {attachClickEvent} from '../../../../helpers/dom/clickEvent';\nimport replaceContent from '../../../../helpers/dom/replaceContent';\nimport toggleDisability from '../../../../helpers/dom/toggleDisability';\nimport wrapStickerEmoji from '../../../wrappers/stickerEmoji';\nimport SettingSection from '../../../settingSection';\n\nexport default class AppTwoStepVerificationEmailConfirmationTab extends SliderSuperTab {\n public codeInputField: CodeInputField;\n public state: AccountPassword;\n public email: string;\n public length: number;\n public isFirst = false;\n\n public init() {\n this.container.classList.add('two-step-verification', 'two-step-verification-email-confirmation');\n this.setTitle('TwoStepAuth.RecoveryTitle');\n\n const section = new SettingSection({\n captionOld: true,\n noDelimiter: true\n });\n\n _i18n(section.caption, 'TwoStepAuth.ConfirmEmailCodeDesc', [this.email]);\n\n const emoji = '📬';\n const stickerContainer = document.createElement('div');\n\n wrapStickerEmoji({\n div: stickerContainer,\n width: 160,\n height: 160,\n emoji\n });\n\n section.content.append(stickerContainer);\n\n const inputContent = section.generateContentElement();\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n const inputField = this.codeInputField = new CodeInputField({\n name: 'recovery-email-code',\n label: 'TwoStepAuth.RecoveryCode',\n length: this.length,\n onFill: (code) => {\n freeze(true);\n\n this.managers.passwordManager.confirmPasswordEmail('' + code)\n .then((value) => {\n if(!value) {\n\n }\n\n goNext();\n })\n .catch((err) => {\n switch(err.type) {\n case 'CODE_INVALID':\n inputField.input.classList.add('error');\n replaceContent(inputField.label, i18n('TwoStepAuth.RecoveryCodeInvalid'));\n break;\n\n case 'EMAIL_HASH_EXPIRED':\n inputField.input.classList.add('error');\n replaceContent(inputField.label, i18n('TwoStepAuth.RecoveryCodeExpired'));\n break;\n\n default:\n console.error('confirm error', err);\n break;\n }\n\n freeze(false);\n });\n }\n });\n\n const btnChange = Button('btn-primary btn-primary-transparent primary', {text: 'TwoStepAuth.EmailCodeChangeEmail'});\n const btnResend = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'ResendCode'});\n\n const goNext = () => {\n this.slider.createTab(AppTwoStepVerificationSetTab).open();\n };\n\n const freeze = (disable: boolean) => {\n toggleDisability([inputField.input, btnChange, btnResend], disable);\n };\n\n attachClickEvent(btnChange, (e) => {\n freeze(true);\n this.managers.passwordManager.cancelPasswordEmail().then((value) => {\n this.slider.sliceTabsUntilTab(AppTwoStepVerificationEmailTab, this);\n this.close();\n }, () => {\n freeze(false);\n });\n });\n\n attachClickEvent(btnResend, (e) => {\n freeze(true);\n const d = putPreloader(btnResend);\n this.managers.passwordManager.resendPasswordEmail().then((value) => {\n d.remove();\n freeze(false);\n });\n });\n\n inputWrapper.append(inputField.container, btnChange, btnResend);\n\n inputContent.append(inputWrapper);\n\n this.scrollable.container.append(section.container);\n }\n\n onOpenAfterTimeout() {\n if(!canFocus(this.isFirst)) return;\n this.codeInputField.input.focus();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AccountPassword} from '../../../../layer';\nimport Button from '../../../button';\nimport {SliderSuperTab} from '../../../slider';\nimport InputField from '../../../inputField';\nimport {putPreloader} from '../../../putPreloader';\nimport AppTwoStepVerificationSetTab from './passwordSet';\nimport AppTwoStepVerificationEmailConfirmationTab from './emailConfirmation';\nimport PopupPeer from '../../../popups/peer';\nimport cancelEvent from '../../../../helpers/dom/cancelEvent';\nimport {canFocus} from '../../../../helpers/dom/canFocus';\nimport {attachClickEvent} from '../../../../helpers/dom/clickEvent';\nimport matchEmail from '../../../../lib/richTextProcessor/matchEmail';\nimport wrapStickerEmoji from '../../../wrappers/stickerEmoji';\nimport SettingSection from '../../../settingSection';\nimport PopupElement from '../../../popups';\n\nexport default class AppTwoStepVerificationEmailTab extends SliderSuperTab {\n public inputField: InputField;\n public state: AccountPassword;\n public plainPassword: string;\n public newPassword: string;\n public hint: string;\n public isFirst = false;\n\n public init() {\n this.container.classList.add('two-step-verification', 'two-step-verification-email');\n this.setTitle('RecoveryEmailTitle');\n\n const section = new SettingSection({\n captionOld: true,\n noDelimiter: true\n });\n\n const emoji = '💌';\n const stickerContainer = document.createElement('div');\n\n wrapStickerEmoji({\n div: stickerContainer,\n width: 160,\n height: 160,\n emoji\n });\n\n section.content.append(stickerContainer);\n\n const inputContent = section.generateContentElement();\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n const inputField = this.inputField = new InputField({\n name: 'recovery-email',\n label: 'RecoveryEmail',\n plainText: true\n });\n\n inputField.input.addEventListener('keypress', (e) => {\n if(e.key === 'Enter') {\n cancelEvent(e);\n return onContinueClick();\n }\n });\n\n inputField.input.addEventListener('input', (e) => {\n inputField.input.classList.remove('error');\n });\n\n const btnContinue = Button('btn-primary btn-color-primary', {text: 'Continue'});\n const btnSkip = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'YourEmailSkip'});\n\n const goNext = () => {\n this.slider.createTab(AppTwoStepVerificationSetTab).open();\n };\n\n const onContinueClick = () => {\n const email = inputField.value.trim();\n const match = matchEmail(email);\n if(!match || match[0].length !== email.length) {\n inputField.input.classList.add('error');\n return;\n }\n\n toggleButtons(true);\n const d = putPreloader(btnContinue);\n\n this.managers.passwordManager.updateSettings({\n hint: this.hint,\n currentPassword: this.plainPassword,\n newPassword: this.newPassword,\n email\n }).then((value) => {\n goNext();\n }, (err) => {\n if(err.type.includes('EMAIL_UNCONFIRMED')) {\n const symbols = +err.type.match(/^EMAIL_UNCONFIRMED_(\\d+)/)[1];\n\n const tab = this.slider.createTab(AppTwoStepVerificationEmailConfirmationTab);\n tab.state = this.state;\n tab.email = email;\n tab.length = symbols;\n tab.open();\n } else {\n console.log('password set error', err);\n }\n\n toggleButtons(false);\n d.remove();\n });\n };\n attachClickEvent(btnContinue, onContinueClick);\n\n const toggleButtons = (freeze: boolean) => {\n if(freeze) {\n btnContinue.setAttribute('disabled', 'true');\n btnSkip.setAttribute('disabled', 'true');\n } else {\n btnContinue.removeAttribute('disabled');\n btnSkip.removeAttribute('disabled');\n }\n };\n\n attachClickEvent(btnSkip, (e) => {\n const popup = PopupElement.createPopup(PopupPeer, 'popup-skip-email', {\n buttons: [{\n langKey: 'Cancel',\n isCancel: true\n }, {\n langKey: 'YourEmailSkip',\n callback: () => {\n // inputContent.classList.add('sidebar-left-section-disabled');\n toggleButtons(true);\n putPreloader(btnSkip);\n this.managers.passwordManager.updateSettings({\n hint: this.hint,\n currentPassword: this.plainPassword,\n newPassword: this.newPassword,\n email: ''\n }).then(() => {\n goNext();\n }, (err) => {\n toggleButtons(false);\n });\n },\n isDanger: true\n }],\n titleLangKey: 'YourEmailSkipWarning',\n descriptionLangKey: 'YourEmailSkipWarningText'\n });\n\n popup.show();\n });\n\n inputWrapper.append(inputField.container, btnContinue, btnSkip);\n\n inputContent.append(inputWrapper);\n\n this.scrollable.container.append(section.container);\n }\n\n onOpenAfterTimeout() {\n if(!canFocus(this.isFirst)) return;\n this.inputField.input.focus();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AccountPassword} from '../../../../layer';\nimport Button from '../../../button';\nimport {SliderSuperTab} from '../../../slider';\nimport InputField from '../../../inputField';\nimport AppTwoStepVerificationEmailTab from './email';\nimport {toast} from '../../../toast';\nimport I18n from '../../../../lib/langPack';\nimport cancelEvent from '../../../../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../../../../helpers/dom/clickEvent';\nimport wrapStickerEmoji from '../../../wrappers/stickerEmoji';\nimport SettingSection from '../../../settingSection';\n\nexport default class AppTwoStepVerificationHintTab extends SliderSuperTab {\n public inputField: InputField;\n public state: AccountPassword;\n public plainPassword: string;\n public newPassword: string;\n\n public init() {\n this.container.classList.add('two-step-verification', 'two-step-verification-hint');\n this.setTitle('TwoStepAuth.SetupHintTitle');\n\n const section = new SettingSection({\n noDelimiter: true\n });\n\n const emoji = '💡';\n const stickerContainer = document.createElement('div');\n wrapStickerEmoji({\n div: stickerContainer,\n width: 160,\n height: 160,\n emoji\n });\n\n section.content.append(stickerContainer);\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n const inputField = this.inputField = new InputField({\n name: 'hint',\n label: 'TwoStepAuth.SetupHintPlaceholder'\n });\n\n inputField.input.addEventListener('keypress', (e) => {\n if(e.key === 'Enter') {\n cancelEvent(e);\n return inputField.value ? onContinueClick() : onSkipClick();\n }\n });\n\n const goNext = (e?: Event, saveHint?: boolean) => {\n if(e) {\n cancelEvent(e);\n }\n\n const hint = saveHint ? inputField.value : undefined;\n if(hint && this.newPassword === hint) {\n toast(I18n.format('PasswordAsHintError', true));\n return;\n }\n\n const tab = this.slider.createTab(AppTwoStepVerificationEmailTab);\n tab.state = this.state;\n tab.plainPassword = this.plainPassword;\n tab.newPassword = this.newPassword;\n tab.hint = hint;\n\n tab.open();\n };\n\n const btnContinue = Button('btn-primary btn-color-primary', {text: 'Continue'});\n const btnSkip = Button('btn-primary btn-secondary btn-primary-transparent primary', {text: 'YourEmailSkip'});\n\n const onContinueClick = (e?: Event) => goNext(e, true);\n const onSkipClick = (e?: Event) => goNext(e, false);\n attachClickEvent(btnContinue, onContinueClick);\n attachClickEvent(btnSkip, onSkipClick);\n\n inputWrapper.append(inputField.container, btnContinue, btnSkip);\n\n section.content.append(inputWrapper);\n\n this.scrollable.container.append(section.container);\n }\n\n onOpenAfterTimeout() {\n this.inputField.input.focus();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AccountPassword} from '../../../../layer';\nimport Button from '../../../button';\nimport PasswordInputField from '../../../passwordInputField';\nimport {SliderSuperTab} from '../../../slider';\nimport TrackingMonkey from '../../../monkeys/tracking';\nimport AppTwoStepVerificationHintTab from './hint';\nimport {InputState} from '../../../inputField';\nimport cancelEvent from '../../../../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../../../../helpers/dom/clickEvent';\nimport SettingSection from '../../../settingSection';\n\nexport default class AppTwoStepVerificationReEnterPasswordTab extends SliderSuperTab {\n public state: AccountPassword;\n public passwordInputField: PasswordInputField;\n public plainPassword: string;\n public newPassword: string;\n\n public init() {\n this.container.classList.add('two-step-verification', 'two-step-verification-enter-password', 'two-step-verification-re-enter-password');\n this.setTitle('PleaseReEnterPassword');\n\n const section = new SettingSection({\n noDelimiter: true\n });\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n const passwordInputField = this.passwordInputField = new PasswordInputField({\n name: 're-enter-password',\n label: 'PleaseReEnterPassword'\n });\n\n const monkey = new TrackingMonkey(passwordInputField, 157);\n\n const btnContinue = Button('btn-primary btn-color-primary', {text: 'Continue'});\n\n inputWrapper.append(passwordInputField.container, btnContinue);\n section.content.append(monkey.container, inputWrapper);\n\n this.scrollable.container.append(section.container);\n\n passwordInputField.input.addEventListener('keypress', (e) => {\n if(passwordInputField.input.classList.contains('error')) {\n passwordInputField.setState(InputState.Neutral);\n }\n\n if(e.key === 'Enter') {\n return onContinueClick();\n }\n });\n\n const verifyInput = () => {\n if(this.newPassword !== passwordInputField.value) {\n passwordInputField.setError();\n return false;\n }\n\n return true;\n };\n\n const onContinueClick = (e?: Event) => {\n if(e) {\n cancelEvent(e);\n }\n\n if(!verifyInput()) return;\n\n const tab = this.slider.createTab(AppTwoStepVerificationHintTab);\n tab.state = this.state;\n tab.plainPassword = this.plainPassword;\n tab.newPassword = this.newPassword;\n tab.open();\n };\n attachClickEvent(btnContinue, onContinueClick);\n\n return monkey.load();\n }\n\n onOpenAfterTimeout() {\n this.passwordInputField.input.focus();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport AppTwoStepVerificationTab from '.';\nimport cancelEvent from '../../../../helpers/dom/cancelEvent';\nimport {canFocus} from '../../../../helpers/dom/canFocus';\nimport {attachClickEvent} from '../../../../helpers/dom/clickEvent';\nimport replaceContent from '../../../../helpers/dom/replaceContent';\nimport setInnerHTML from '../../../../helpers/dom/setInnerHTML';\nimport {AccountPassword} from '../../../../layer';\nimport I18n, {i18n} from '../../../../lib/langPack';\nimport wrapEmojiText from '../../../../lib/richTextProcessor/wrapEmojiText';\nimport Button from '../../../button';\nimport {putPreloader} from '../../../putPreloader';\nimport PasswordMonkey from '../../../monkeys/password';\nimport PasswordInputField from '../../../passwordInputField';\nimport {SliderSuperTab} from '../../../slider';\nimport AppTwoStepVerificationReEnterPasswordTab from './reEnterPassword';\nimport SettingSection from '../../../settingSection';\n\nexport default class AppTwoStepVerificationEnterPasswordTab extends SliderSuperTab {\n public state: AccountPassword;\n public passwordInputField: PasswordInputField;\n public plainPassword: string;\n public isFirst = true;\n\n public init() {\n const isNew = !this.state.pFlags.has_password || this.plainPassword;\n this.container.classList.add('two-step-verification', 'two-step-verification-enter-password');\n this.setTitle(isNew ? 'PleaseEnterFirstPassword' : 'PleaseEnterCurrentPassword');\n\n const section = new SettingSection({\n noDelimiter: true\n });\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n const passwordInputField = this.passwordInputField = new PasswordInputField({\n name: 'enter-password',\n label: isNew ? 'PleaseEnterFirstPassword' : (this.state.hint ? undefined : 'LoginPassword'),\n labelText: !isNew && this.state.hint ? wrapEmojiText(this.state.hint) : undefined\n });\n\n const monkey = new PasswordMonkey(passwordInputField, 157);\n\n const btnContinue = Button('btn-primary btn-color-primary');\n const textEl = new I18n.IntlElement({key: 'Continue'});\n\n btnContinue.append(textEl.element);\n\n inputWrapper.append(passwordInputField.container, btnContinue);\n section.content.append(monkey.container, inputWrapper);\n\n this.scrollable.container.append(section.container);\n\n passwordInputField.input.addEventListener('keypress', (e) => {\n if(passwordInputField.input.classList.contains('error')) {\n passwordInputField.input.classList.remove('error');\n textEl.key = 'Continue';\n textEl.update();\n }\n\n if(e.key === 'Enter') {\n return onContinueClick();\n }\n });\n\n const verifyInput = () => {\n if(!passwordInputField.value.length) {\n passwordInputField.input.classList.add('error');\n return false;\n }\n\n return true;\n };\n\n let onContinueClick: (e?: Event) => void;\n if(!isNew) {\n let getStateInterval: number;\n\n const getState = () => {\n // * just to check session relevance\n if(!getStateInterval) {\n getStateInterval = window.setInterval(getState, 10e3);\n }\n\n return this.managers.passwordManager.getState().then((_state) => {\n this.state = _state;\n\n if(this.state.hint) {\n setInnerHTML(passwordInputField.label, wrapEmojiText(this.state.hint));\n } else {\n replaceContent(passwordInputField.label, i18n('LoginPassword'));\n }\n });\n };\n\n const submit = (e?: Event) => {\n if(!verifyInput()) {\n cancelEvent(e);\n return;\n }\n\n btnContinue.setAttribute('disabled', 'true');\n textEl.key = 'PleaseWait';\n textEl.update();\n const preloader = putPreloader(btnContinue);\n\n const plainPassword = passwordInputField.value;\n this.managers.passwordManager.check(passwordInputField.value, this.state).then((auth) => {\n console.log(auth);\n\n if(auth._ === 'auth.authorization') {\n clearInterval(getStateInterval);\n if(monkey) monkey.remove();\n const tab = this.slider.createTab(AppTwoStepVerificationTab);\n tab.state = this.state;\n tab.plainPassword = plainPassword;\n tab.open();\n this.slider.removeTabFromHistory(this);\n }\n }, (err) => {\n btnContinue.removeAttribute('disabled');\n passwordInputField.input.classList.add('error');\n\n switch(err.type) {\n default:\n // btnContinue.innerText = err.type;\n textEl.key = 'PASSWORD_HASH_INVALID';\n textEl.update();\n preloader.remove();\n passwordInputField.select();\n break;\n }\n\n getState();\n });\n };\n\n onContinueClick = submit;\n\n getState();\n } else {\n onContinueClick = (e) => {\n if(e) {\n cancelEvent(e);\n }\n\n if(!verifyInput()) return;\n\n const tab = this.slider.createTab(AppTwoStepVerificationReEnterPasswordTab);\n tab.state = this.state;\n tab.newPassword = passwordInputField.value;\n tab.plainPassword = this.plainPassword;\n tab.open();\n };\n }\n\n attachClickEvent(btnContinue, onContinueClick);\n\n return monkey.load();\n }\n\n onOpenAfterTimeout() {\n if(!canFocus(this.isFirst)) return;\n this.passwordInputField.input.focus();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {attachClickEvent} from '../../../../helpers/dom/clickEvent';\nimport {AccountPassword} from '../../../../layer';\nimport {_i18n} from '../../../../lib/langPack';\nimport Button from '../../../button';\nimport PopupElement from '../../../popups';\nimport PopupPeer from '../../../popups/peer';\nimport SettingSection from '../../../settingSection';\nimport {SliderSuperTab} from '../../../slider';\nimport wrapStickerEmoji from '../../../wrappers/stickerEmoji';\nimport AppSettingsTab from '../settings';\nimport AppTwoStepVerificationEmailTab from './email';\nimport AppTwoStepVerificationEnterPasswordTab from './enterPassword';\n\nexport default class AppTwoStepVerificationTab extends SliderSuperTab {\n public state: AccountPassword;\n public plainPassword: string;\n\n public init() {\n this.container.classList.add('two-step-verification', 'two-step-verification-main');\n this.setTitle('TwoStepVerificationTitle');\n\n const section = new SettingSection({\n captionOld: true,\n noDelimiter: true\n });\n\n const emoji = '🔐';\n const stickerContainer = document.createElement('div');\n\n wrapStickerEmoji({\n div: stickerContainer,\n width: 168,\n height: 168,\n emoji\n });\n\n section.content.append(stickerContainer);\n\n const c = section.generateContentElement();\n if(this.state.pFlags.has_password) {\n _i18n(section.caption, 'TwoStepAuth.GenericHelp');\n\n const btnChangePassword = Button('btn-primary btn-transparent', {icon: 'edit', text: 'TwoStepAuth.ChangePassword'});\n const btnDisablePassword = Button('btn-primary btn-transparent', {icon: 'passwordoff', text: 'TwoStepAuth.RemovePassword'});\n const btnSetRecoveryEmail = Button('btn-primary btn-transparent', {icon: 'email', text: this.state.pFlags.has_recovery ? 'TwoStepAuth.ChangeEmail' : 'TwoStepAuth.SetupEmail'});\n\n attachClickEvent(btnChangePassword, () => {\n const tab = this.slider.createTab(AppTwoStepVerificationEnterPasswordTab);\n tab.state = this.state;\n tab.plainPassword = this.plainPassword;\n tab.open();\n });\n\n attachClickEvent(btnDisablePassword, () => {\n const popup = PopupElement.createPopup(PopupPeer, 'popup-disable-password', {\n buttons: [{\n langKey: 'Disable',\n callback: () => {\n this.managers.passwordManager.updateSettings({currentPassword: this.plainPassword}).then(() => {\n this.slider.sliceTabsUntilTab(AppSettingsTab, this);\n this.close();\n });\n },\n isDanger: true\n }],\n titleLangKey: 'TurnPasswordOffQuestionTitle',\n descriptionLangKey: 'TurnPasswordOffQuestion'\n });\n\n popup.show();\n });\n\n attachClickEvent(btnSetRecoveryEmail, () => {\n const tab = this.slider.createTab(AppTwoStepVerificationEmailTab);\n tab.state = this.state;\n tab.hint = this.state.hint;\n tab.plainPassword = this.plainPassword;\n tab.newPassword = this.plainPassword;\n tab.isFirst = true;\n tab.open();\n });\n\n c.append(btnChangePassword, btnDisablePassword, btnSetRecoveryEmail);\n } else {\n _i18n(section.caption, 'TwoStepAuth.SetPasswordHelp');\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n const btnSetPassword = Button('btn-primary btn-color-primary', {text: 'TwoStepVerificationSetPassword'});\n\n inputWrapper.append(btnSetPassword);\n c.append(inputWrapper);\n\n attachClickEvent(btnSetPassword, (e) => {\n const tab = this.slider.createTab(AppTwoStepVerificationEnterPasswordTab);\n tab.state = this.state;\n tab.open();\n });\n }\n\n this.scrollable.container.append(section.container);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTabEventable} from '../../../sliderTab';\nimport PrivacySection from '../../../privacySection';\nimport {LangPackKey} from '../../../../lib/langPack';\n\nexport default class AppPrivacyLastSeenTab extends SliderSuperTabEventable {\n public init() {\n this.container.classList.add('privacy-tab', 'privacy-last-seen');\n this.setTitle('PrivacyLastSeen');\n\n const caption: LangPackKey = 'PrivacySettingsController.LastSeenDescription';\n new PrivacySection({\n tab: this,\n title: 'LastSeenTitle',\n inputKey: 'inputPrivacyKeyStatusTimestamp',\n captions: [caption, caption, caption],\n exceptionTexts: ['PrivacySettingsController.NeverShare', 'PrivacySettingsController.AlwaysShare'],\n appendTo: this.scrollable,\n managers: this.managers\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTabEventable} from '../../../sliderTab';\nimport PrivacySection from '../../../privacySection';\nimport {LangPackKey} from '../../../../lib/langPack';\nimport PrivacyType from '../../../../lib/appManagers/utils/privacy/privacyType';\n\nexport default class AppPrivacyProfilePhotoTab extends SliderSuperTabEventable {\n public init() {\n this.container.classList.add('privacy-tab', 'privacy-profile-photo');\n this.setTitle('PrivacyProfilePhoto');\n\n const caption: LangPackKey = 'PrivacySettingsController.ProfilePhoto.CustomHelp';\n new PrivacySection({\n tab: this,\n title: 'PrivacyProfilePhotoTitle',\n inputKey: 'inputPrivacyKeyProfilePhoto',\n captions: [caption, caption, caption],\n exceptionTexts: ['PrivacySettingsController.NeverShare', 'PrivacySettingsController.AlwaysShare'],\n appendTo: this.scrollable,\n skipTypes: [PrivacyType.Nobody],\n managers: this.managers\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTabEventable} from '../../../sliderTab';\nimport PrivacySection from '../../../privacySection';\nimport {LangPackKey} from '../../../../lib/langPack';\n\nexport default class AppPrivacyForwardMessagesTab extends SliderSuperTabEventable {\n public init() {\n this.container.classList.add('privacy-tab', 'privacy-forward-messages');\n this.setTitle('PrivacySettings.Forwards');\n\n const caption: LangPackKey = 'PrivacySettingsController.Forwards.CustomHelp';\n new PrivacySection({\n tab: this,\n title: 'PrivacyForwardsTitle',\n inputKey: 'inputPrivacyKeyForwards',\n captions: [caption, caption, caption],\n exceptionTexts: ['PrivacySettingsController.NeverAllow', 'PrivacySettingsController.AlwaysAllow'],\n appendTo: this.scrollable,\n managers: this.managers\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTabEventable} from '../../../sliderTab';\nimport PrivacySection from '../../../privacySection';\nimport {LangPackKey} from '../../../../lib/langPack';\nimport PrivacyType from '../../../../lib/appManagers/utils/privacy/privacyType';\n\nexport default class AppPrivacyAddToGroupsTab extends SliderSuperTabEventable {\n public init() {\n this.container.classList.add('privacy-tab', 'privacy-add-to-groups');\n this.setTitle('PrivacySettings.Groups');\n\n const caption: LangPackKey = 'PrivacySettingsController.GroupDescription';\n new PrivacySection({\n tab: this,\n title: 'WhoCanAddMe',\n inputKey: 'inputPrivacyKeyChatInvite',\n captions: [caption, caption, caption],\n exceptionTexts: ['PrivacySettingsController.NeverAllow', 'PrivacySettingsController.AlwaysAllow'],\n appendTo: this.scrollable,\n skipTypes: [PrivacyType.Nobody],\n managers: this.managers\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTabEventable} from '../../../sliderTab';\nimport PrivacySection from '../../../privacySection';\nimport {LangPackKey} from '../../../../lib/langPack';\n\nexport default class AppPrivacyCallsTab extends SliderSuperTabEventable {\n public init() {\n this.container.classList.add('privacy-tab', 'privacy-calls');\n this.setTitle('PrivacySettings.VoiceCalls');\n\n const caption: LangPackKey = 'PrivacySettingsController.PhoneCallDescription';\n new PrivacySection({\n tab: this,\n title: 'WhoCanCallMe',\n inputKey: 'inputPrivacyKeyPhoneCall',\n captions: [caption, caption, caption],\n exceptionTexts: ['PrivacySettingsController.NeverAllow', 'PrivacySettingsController.AlwaysAllow'],\n appendTo: this.scrollable,\n managers: this.managers\n });\n\n {\n const caption: LangPackKey = 'PrivacySettingsController.P2p.Desc';\n new PrivacySection({\n tab: this,\n title: 'PrivacyP2PHeader',\n inputKey: 'inputPrivacyKeyPhoneP2P',\n captions: [caption, caption, caption],\n exceptionTexts: ['PrivacySettingsController.NeverAllow', 'PrivacySettingsController.AlwaysAllow'],\n appendTo: this.scrollable,\n managers: this.managers\n });\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport Button from '../../button';\nimport Row from '../../row';\nimport {Authorization} from '../../../layer';\nimport {formatDateAccordingToTodayNew} from '../../../helpers/date';\nimport {ButtonMenuSync} from '../../buttonMenu';\nimport {toast} from '../../toast';\nimport I18n from '../../../lib/langPack';\nimport PopupPeer from '../../popups/peer';\nimport findUpClassName from '../../../helpers/dom/findUpClassName';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport toggleDisability from '../../../helpers/dom/toggleDisability';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport findAndSplice from '../../../helpers/array/findAndSplice';\nimport {attachContextMenuListener} from '../../../helpers/dom/attachContextMenuListener';\nimport positionMenu from '../../../helpers/positionMenu';\nimport contextMenuController from '../../../helpers/contextMenuController';\nimport SettingSection from '../../settingSection';\nimport PopupElement from '../../popups';\n\nexport default class AppActiveSessionsTab extends SliderSuperTabEventable {\n public authorizations: Authorization.authorization[];\n private menuElement: HTMLElement;\n\n public init() {\n this.container.classList.add('active-sessions-container');\n this.setTitle('SessionsTitle');\n\n const Session = (auth: Authorization.authorization) => {\n const row = new Row({\n title: [auth.app_name, auth.app_version].join(' '),\n subtitle: [auth.ip, auth.country].join(' - '),\n clickable: true,\n titleRight: auth.pFlags.current ? undefined : formatDateAccordingToTodayNew(new Date(Math.max(auth.date_active, auth.date_created) * 1000))\n });\n\n row.container.dataset.hash = '' + auth.hash;\n\n row.midtitle.textContent = [auth.device_model, auth.system_version || auth.platform].filter(Boolean).join(', ');\n\n return row;\n };\n\n const authorizations = this.authorizations.slice();\n\n {\n const section = new SettingSection({\n name: 'CurrentSession',\n caption: 'ClearOtherSessionsHelp'\n });\n\n const auth = findAndSplice(authorizations, auth => auth.pFlags.current);\n const session = Session(auth);\n\n section.content.append(session.container);\n\n if(authorizations.length) {\n const btnTerminate = Button('btn-primary btn-transparent danger', {icon: 'stop', text: 'TerminateAllSessions'});\n attachClickEvent(btnTerminate, (e) => {\n PopupElement.createPopup(PopupPeer, 'revoke-session', {\n buttons: [{\n langKey: 'Terminate',\n isDanger: true,\n callback: () => {\n const toggle = toggleDisability([btnTerminate], true);\n this.managers.apiManager.invokeApi('auth.resetAuthorizations').then((value) => {\n // toggleDisability([btnTerminate], false);\n btnTerminate.remove();\n otherSection.container.remove();\n }, onError).finally(() => {\n toggle();\n });\n }\n }],\n titleLangKey: 'AreYouSureSessionsTitle',\n descriptionLangKey: 'AreYouSureSessions'\n }).show();\n }, {listenerSetter: this.listenerSetter});\n\n section.content.append(btnTerminate);\n }\n\n this.scrollable.append(section.container);\n }\n\n if(!authorizations.length) {\n return;\n }\n\n const otherSection = new SettingSection({\n name: 'OtherSessions',\n caption: 'SessionsListInfo'\n });\n\n authorizations.forEach((auth) => {\n otherSection.content.append(Session(auth).container);\n });\n\n this.scrollable.append(otherSection.container);\n\n const onError = (err: any) => {\n if(err.type === 'FRESH_RESET_AUTHORISATION_FORBIDDEN') {\n toast(I18n.format('RecentSessions.Error.FreshReset', true));\n }\n };\n\n let target: HTMLElement;\n const onTerminateClick = () => {\n const hash = target.dataset.hash;\n\n PopupElement.createPopup(PopupPeer, 'revoke-session', {\n buttons: [{\n langKey: 'Terminate',\n isDanger: true,\n callback: () => {\n this.managers.apiManager.invokeApi('account.resetAuthorization', {hash})\n .then((value) => {\n if(value) {\n target.remove();\n }\n }, onError);\n }\n }],\n titleLangKey: 'AreYouSureSessionTitle',\n descriptionLangKey: 'TerminateSessionText'\n }).show();\n };\n\n const element = this.menuElement = ButtonMenuSync({\n buttons: [{\n icon: 'stop',\n text: 'Terminate',\n onClick: onTerminateClick\n }]\n });\n element.id = 'active-sessions-contextmenu';\n element.classList.add('contextmenu');\n\n document.getElementById('page-chats').append(element);\n\n attachContextMenuListener({\n element: this.scrollable.container,\n callback: (e) => {\n target = findUpClassName(e.target, 'row');\n if(!target || target.dataset.hash === '0') {\n return;\n }\n\n if(e instanceof MouseEvent) e.preventDefault();\n // smth\n if(e instanceof MouseEvent) e.cancelBubble = true;\n\n positionMenu(e, element);\n contextMenuController.openBtnMenu(element);\n },\n listenerSetter: this.listenerSetter\n });\n\n attachClickEvent(this.scrollable.container, (e) => {\n target = findUpClassName(e.target, 'row');\n if(!target || target.dataset.hash === '0') {\n return;\n }\n\n onTerminateClick();\n }, {listenerSetter: this.listenerSetter});\n }\n\n onCloseAfterTimeout() {\n this.menuElement?.remove();\n return super.onCloseAfterTimeout();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTab} from '../../slider';\nimport {ButtonMenuSync} from '../../buttonMenu';\nimport appDialogsManager, {DIALOG_LIST_ELEMENT_TAG} from '../../../lib/appManagers/appDialogsManager';\nimport PopupPickUser from '../../popups/pickUser';\nimport rootScope from '../../../lib/rootScope';\nimport findUpTag from '../../../helpers/dom/findUpTag';\nimport ButtonCorner from '../../buttonCorner';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport formatUserPhone from '../../wrappers/formatUserPhone';\nimport getUserStatusString from '../../wrappers/getUserStatusString';\nimport {attachContextMenuListener} from '../../../helpers/dom/attachContextMenuListener';\nimport positionMenu from '../../../helpers/positionMenu';\nimport contextMenuController from '../../../helpers/contextMenuController';\nimport getPeerActiveUsernames from '../../../lib/appManagers/utils/peers/getPeerActiveUsernames';\nimport SettingSection from '../../settingSection';\nimport PopupElement from '../../popups';\n\nexport default class AppBlockedUsersTab extends SliderSuperTab {\n public peerIds: PeerId[];\n private menuElement: HTMLElement;\n\n public init() {\n this.container.classList.add('blocked-users-container');\n this.setTitle('BlockedUsers');\n\n const section = new SettingSection({\n caption: 'BlockedUsersInfo'\n });\n\n section.caption.parentElement.prepend(section.caption);\n\n this.scrollable.append(section.container);\n\n const btnAdd = ButtonCorner({icon: 'add', className: 'is-visible'});\n this.content.append(btnAdd);\n\n attachClickEvent(btnAdd, (e) => {\n PopupElement.createPopup(PopupPickUser, {\n peerTypes: ['contacts'],\n placeholder: 'BlockModal.Search.Placeholder',\n onSelect: (peerId) => {\n // console.log('block', peerId);\n this.managers.appUsersManager.toggleBlock(peerId, true);\n }\n });\n }, {listenerSetter: this.listenerSetter});\n\n const list = appDialogsManager.createChatList();\n this.scrollable.container.classList.add('chatlist-container');\n section.content.append(list);\n\n const add = async(peerId: PeerId, append: boolean) => {\n const {dom} = appDialogsManager.addDialogNew({\n peerId: peerId,\n container: list,\n rippleEnabled: true,\n avatarSize: 'abitbigger',\n append\n });\n\n const user = await this.managers.appUsersManager.getUser(peerId.toUserId());\n if(!user) {\n return;\n }\n\n const usernames = getPeerActiveUsernames(user);\n const username = usernames[0];\n if(user.pFlags.bot) {\n dom.lastMessageSpan.append('@' + username);\n } else {\n if(user.phone) dom.lastMessageSpan.textContent = formatUserPhone(user.phone);\n else dom.lastMessageSpan.append(username ? '@' + username : getUserStatusString(user));\n }\n };\n\n for(const peerId of this.peerIds) {\n add(peerId, true);\n }\n\n let target: HTMLElement;\n const onUnblock = () => {\n const peerId = target.dataset.peerId.toPeerId();\n this.managers.appUsersManager.toggleBlock(peerId, false);\n };\n\n const element = this.menuElement = ButtonMenuSync({\n buttons: [{\n icon: 'lockoff',\n text: 'Unblock',\n onClick: onUnblock,\n options: {listenerSetter: this.listenerSetter}\n }]\n });\n element.id = 'blocked-users-contextmenu';\n element.classList.add('contextmenu');\n\n document.getElementById('page-chats').append(element);\n\n attachContextMenuListener({\n element: this.scrollable.container,\n callback: (e) => {\n target = findUpTag(e.target, DIALOG_LIST_ELEMENT_TAG);\n if(!target) {\n return;\n }\n\n if(e instanceof MouseEvent) e.preventDefault();\n // smth\n if(e instanceof MouseEvent) e.cancelBubble = true;\n\n positionMenu(e, element);\n contextMenuController.openBtnMenu(element);\n },\n listenerSetter: this.listenerSetter\n });\n\n this.listenerSetter.add(rootScope)('peer_block', (update) => {\n const {peerId, blocked} = update;\n const li = list.querySelector(`[data-peer-id=\"${peerId}\"]`);\n if(blocked) {\n if(!li) {\n add(peerId, false);\n }\n } else {\n if(li) {\n li.remove();\n }\n }\n });\n\n const LOAD_COUNT = 50;\n let loading = false;\n this.scrollable.onScrolledBottom = () => {\n if(loading) {\n return;\n }\n\n loading = true;\n this.managers.appUsersManager.getBlocked(list.childElementCount, LOAD_COUNT).then((res) => {\n for(const peerId of res.peerIds) {\n add(peerId, true);\n }\n\n if(res.peerIds.length < LOAD_COUNT || list.childElementCount === res.count) {\n this.scrollable.onScrolledBottom = null;\n }\n\n this.scrollable.checkForTriggers();\n }).finally(() => {\n loading = false;\n });\n };\n }\n\n onOpenAfterTimeout() {\n this.scrollable.onScroll();\n }\n\n onCloseAfterTimeout() {\n if(this.menuElement) {\n this.menuElement.remove();\n }\n\n return super.onCloseAfterTimeout();\n }\n}\n","export default function convertKeyToInputKey(key: string) {\n key = key[0].toUpperCase() + key.slice(1);\n key = 'input' + key;\n return key;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTabEventable} from '../../../sliderTab';\nimport PrivacySection from '../../../privacySection';\nimport {LangPackKey} from '../../../../lib/langPack';\n\nexport default class AppPrivacyVoicesTab extends SliderSuperTabEventable {\n public init() {\n this.container.classList.add('privacy-tab', 'privacy-voices');\n this.setTitle('PrivacyVoiceMessages');\n\n const caption: LangPackKey = 'PrivacyVoiceMessagesInfo';\n new PrivacySection({\n tab: this,\n title: 'PrivacyVoiceMessagesTitle',\n inputKey: 'inputPrivacyKeyVoiceMessages',\n captions: [caption, caption, caption],\n exceptionTexts: ['PrivacySettingsController.NeverAllow', 'PrivacySettingsController.AlwaysAllow'],\n appendTo: this.scrollable,\n managers: this.managers\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {formatDateAccordingToTodayNew} from '../../../helpers/date';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport findUpClassName from '../../../helpers/dom/findUpClassName';\nimport toggleDisability from '../../../helpers/dom/toggleDisability';\nimport {WebAuthorization} from '../../../layer';\nimport AvatarElement from '../../avatar';\nimport Button from '../../button';\nimport confirmationPopup from '../../confirmationPopup';\nimport Row from '../../row';\nimport SettingSection from '../../settingSection';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport wrapPeerTitle from '../../wrappers/peerTitle';\n\nexport default class AppActiveWebSessionsTab extends SliderSuperTabEventable {\n public async init(sessions: WebAuthorization[]) {\n this.container.classList.add('active-sessions-container');\n this.setTitle('WebSessionsTitle');\n\n const Session = async(auth: WebAuthorization) => {\n const peerId = auth.bot_id.toPeerId();\n const row = new Row({\n title: await wrapPeerTitle({peerId}),\n subtitle: [auth.ip, auth.region].join(' - '),\n clickable: true,\n titleRight: formatDateAccordingToTodayNew(new Date(Math.max(auth.date_active, auth.date_created) * 1000))\n });\n\n const media = row.createMedia('big');\n const avatar = new AvatarElement();\n avatar.classList.add('avatar-48');\n await avatar.updateWithOptions({peerId});\n media.append(avatar);\n\n row.container.dataset.hash = '' + auth.hash;\n row.container.dataset.peerId = '' + peerId;\n\n row.midtitle.textContent = [auth.domain, auth.browser, auth.platform].filter(Boolean).join(', ');\n\n return row;\n };\n\n {\n const section = new SettingSection({\n caption: 'ClearOtherWebSessionsHelp'\n });\n\n const btnTerminate = Button('btn-primary btn-transparent danger', {icon: 'stop', text: 'TerminateAllWebSessions'});\n\n attachClickEvent(btnTerminate, async() => {\n await confirmationPopup({\n descriptionLangKey: 'AreYouSureWebSessions',\n button: {\n langKey: 'Disconnect',\n isDanger: true\n }\n });\n\n const toggle = toggleDisability([btnTerminate], true);\n this.managers.appSeamlessLoginManager.resetWebAuthorizations().then(() => {\n this.close();\n });\n }, {listenerSetter: this.listenerSetter});\n\n section.content.append(btnTerminate);\n\n this.scrollable.append(section.container);\n }\n\n {\n const section = new SettingSection({\n name: 'OtherWebSessions',\n caption: 'TerminateWebSessionInfo'\n });\n\n const rows = await Promise.all(sessions.map(Session));\n section.content.append(...rows.map((row) => row.container));\n\n let leftLength = rows.length;\n attachClickEvent(section.content, async(e) => {\n const row = findUpClassName(e.target, 'row');\n if(!row) {\n return;\n }\n\n await confirmationPopup({\n descriptionLangKey: 'TerminateWebSessionText',\n descriptionLangArgs: [await wrapPeerTitle({peerId: row.dataset.peerId.toPeerId()})],\n button: {\n langKey: 'Disconnect',\n isDanger: true\n }\n });\n\n const hash = row.dataset.hash;\n row.classList.add('is-disabled');\n this.managers.appSeamlessLoginManager.resetWebAuthorization(hash).then(() => {\n if(!--leftLength) {\n this.close();\n } else {\n row.remove();\n }\n });\n }, {listenerSetter: this.listenerSetter});\n\n this.scrollable.append(section.container);\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport SliderSuperTab, {SliderSuperTabEventable} from '../../sliderTab';\nimport Row from '../../row';\nimport {AccountPassword, Authorization, InputPrivacyKey, Updates, WebAuthorization} from '../../../layer';\nimport AppPrivacyPhoneNumberTab from './privacy/phoneNumber';\nimport AppTwoStepVerificationTab from './2fa';\nimport AppTwoStepVerificationEnterPasswordTab from './2fa/enterPassword';\nimport AppTwoStepVerificationEmailConfirmationTab from './2fa/emailConfirmation';\nimport AppPrivacyLastSeenTab from './privacy/lastSeen';\nimport AppPrivacyProfilePhotoTab from './privacy/profilePhoto';\nimport AppPrivacyForwardMessagesTab from './privacy/forwardMessages';\nimport AppPrivacyAddToGroupsTab from './privacy/addToGroups';\nimport AppPrivacyCallsTab from './privacy/calls';\nimport AppActiveSessionsTab from './activeSessions';\nimport AppBlockedUsersTab from './blockedUsers';\nimport rootScope from '../../../lib/rootScope';\nimport {i18n, LangPackKey, _i18n} from '../../../lib/langPack';\nimport replaceContent from '../../../helpers/dom/replaceContent';\nimport CheckboxField from '../../checkboxField';\nimport PopupPeer from '../../popups/peer';\nimport Button from '../../button';\nimport toggleDisability from '../../../helpers/dom/toggleDisability';\nimport convertKeyToInputKey from '../../../helpers/string/convertKeyToInputKey';\nimport getPrivacyRulesDetails from '../../../lib/appManagers/utils/privacy/getPrivacyRulesDetails';\nimport PrivacyType from '../../../lib/appManagers/utils/privacy/privacyType';\nimport confirmationPopup, {PopupConfirmationOptions} from '../../confirmationPopup';\nimport noop from '../../../helpers/noop';\nimport {toastNew} from '../../toast';\nimport AppPrivacyVoicesTab from './privacy/voices';\nimport SettingSection from '../../settingSection';\nimport AppActiveWebSessionsTab from './activeWebSessions';\nimport PopupElement from '../../popups';\n\nexport default class AppPrivacyAndSecurityTab extends SliderSuperTabEventable {\n private activeSessionsRow: Row;\n private authorizations: Authorization.authorization[];\n\n private websitesRow: Row;\n private websites: WebAuthorization[];\n\n public static getInitArgs(fromTab: SliderSuperTab) {\n return {\n appConfig: fromTab.managers.apiManager.getAppConfig(),\n globalPrivacy: fromTab.managers.appPrivacyManager.getGlobalPrivacySettings(),\n contentSettings: fromTab.managers.apiManager.invokeApi('account.getContentSettings'),\n webAuthorizations: fromTab.managers.appSeamlessLoginManager.getWebAuthorizations()\n };\n }\n\n public init(p: ReturnType<typeof AppPrivacyAndSecurityTab['getInitArgs']>) {\n this.container.classList.add('dont-u-dare-block-me');\n this.setTitle('PrivacySettings');\n\n const SUBTITLE: LangPackKey = 'Loading';\n const promises: Promise<any>[] = [];\n\n {\n const section = new SettingSection({noDelimiter: true, caption: 'SessionsInfo'});\n\n let blockedPeerIds: PeerId[];\n const blockedUsersRow = new Row({\n icon: 'deleteuser',\n titleLangKey: 'BlockedUsers',\n subtitleLangKey: SUBTITLE,\n clickable: () => {\n const tab = this.slider.createTab(AppBlockedUsersTab);\n tab.peerIds = blockedPeerIds;\n tab.open();\n },\n listenerSetter: this.listenerSetter\n });\n blockedUsersRow.freezed = true;\n\n let passwordState: AccountPassword;\n const twoFactorRowOptions = {\n icon: 'lock',\n titleLangKey: 'TwoStepVerification' as LangPackKey,\n subtitleLangKey: SUBTITLE,\n clickable: (e: Event) => {\n let tab: AppTwoStepVerificationTab | AppTwoStepVerificationEnterPasswordTab | AppTwoStepVerificationEmailConfirmationTab;\n if(passwordState.pFlags.has_password) {\n tab = this.slider.createTab(AppTwoStepVerificationEnterPasswordTab);\n } else if(passwordState.email_unconfirmed_pattern) {\n tab = this.slider.createTab(AppTwoStepVerificationEmailConfirmationTab);\n tab.email = passwordState.email_unconfirmed_pattern;\n tab.length = 6;\n tab.isFirst = true;\n this.managers.passwordManager.resendPasswordEmail();\n } else {\n tab = this.slider.createTab(AppTwoStepVerificationTab);\n }\n\n tab.state = passwordState;\n tab.open();\n },\n listenerSetter: this.listenerSetter\n };\n\n const twoFactorRow = new Row(twoFactorRowOptions);\n twoFactorRow.freezed = true;\n\n const activeSessionsRow = this.activeSessionsRow = new Row({\n icon: 'activesessions',\n titleLangKey: 'SessionsTitle',\n subtitleLangKey: SUBTITLE,\n clickable: () => {\n const tab = this.slider.createTab(AppActiveSessionsTab);\n tab.authorizations = this.authorizations;\n tab.eventListener.addEventListener('destroy', () => {\n this.updateActiveSessions();\n }, {once: true});\n tab.open();\n },\n listenerSetter: this.listenerSetter\n });\n activeSessionsRow.freezed = true;\n\n const websitesRow = this.websitesRow = new Row({\n icon: 'mention',\n titleLangKey: 'OtherWebSessions',\n subtitleLangKey: SUBTITLE,\n clickable: () => {\n const tab = this.slider.createTab(AppActiveWebSessionsTab);\n tab.eventListener.addEventListener('destroy', () => {\n this.updateActiveWebsites();\n });\n tab.open(this.websites);\n },\n listenerSetter: this.listenerSetter\n });\n websitesRow.freezed = true;\n\n section.content.append(blockedUsersRow.container, twoFactorRow.container, activeSessionsRow.container, websitesRow.container);\n this.scrollable.append(section.container);\n\n const setBlockedCount = (count: number) => {\n if(count) {\n replaceContent(blockedUsersRow.subtitle, i18n('PrivacySettingsController.UserCount', [count]));\n } else {\n replaceContent(blockedUsersRow.subtitle, i18n('BlockedEmpty', [count]));\n }\n };\n\n this.listenerSetter.add(rootScope)('peer_block', () => {\n /* const {blocked, peerId} = update;\n if(!blocked) blockedPeerIds.findAndSplice((p) => p === peerId);\n else blockedPeerIds.unshift(peerId);\n blockedCount += blocked ? 1 : -1;\n setBlockedCount(blockedCount); */\n updateBlocked();\n });\n\n const updateBlocked = () => {\n this.managers.appUsersManager.getBlocked().then((res) => {\n blockedUsersRow.freezed = false;\n setBlockedCount(res.count);\n blockedPeerIds = res.peerIds;\n });\n };\n\n updateBlocked();\n\n this.managers.passwordManager.getState().then((state) => {\n passwordState = state;\n replaceContent(twoFactorRow.subtitle, i18n(state.pFlags.has_password ? 'PrivacyAndSecurity.Item.On' : 'PrivacyAndSecurity.Item.Off'));\n twoFactorRow.freezed = false;\n\n // console.log('password state', state);\n });\n\n this.updateActiveSessions();\n promises.push(this.updateActiveWebsites(p.webAuthorizations));\n }\n\n {\n const section = new SettingSection({name: 'PrivacyTitle', caption: 'GroupsAndChannelsHelp'});\n\n section.content.classList.add('privacy-navigation-container');\n\n const rowsByKeys: Partial<{\n [key in InputPrivacyKey['_']]: Row\n }> = {};\n\n const numberVisibilityRow = rowsByKeys['inputPrivacyKeyPhoneNumber'] = new Row({\n titleLangKey: 'PrivacyPhoneTitle',\n subtitleLangKey: SUBTITLE,\n clickable: () => {\n this.slider.createTab(AppPrivacyPhoneNumberTab).open();\n },\n listenerSetter: this.listenerSetter\n });\n\n const lastSeenTimeRow = rowsByKeys['inputPrivacyKeyStatusTimestamp'] = new Row({\n titleLangKey: 'LastSeenTitle',\n subtitleLangKey: SUBTITLE,\n clickable: () => {\n this.slider.createTab(AppPrivacyLastSeenTab).open();\n },\n listenerSetter: this.listenerSetter\n });\n\n const photoVisibilityRow = rowsByKeys['inputPrivacyKeyProfilePhoto'] = new Row({\n titleLangKey: 'PrivacyProfilePhotoTitle',\n subtitleLangKey: SUBTITLE,\n clickable: () => {\n this.slider.createTab(AppPrivacyProfilePhotoTab).open();\n },\n listenerSetter: this.listenerSetter\n });\n\n const callRow = rowsByKeys['inputPrivacyKeyPhoneCall'] = new Row({\n titleLangKey: 'WhoCanCallMe',\n subtitleLangKey: SUBTITLE,\n clickable: () => {\n this.slider.createTab(AppPrivacyCallsTab).open();\n },\n listenerSetter: this.listenerSetter\n });\n\n const linkAccountRow = rowsByKeys['inputPrivacyKeyForwards'] = new Row({\n titleLangKey: 'PrivacyForwardsTitle',\n subtitleLangKey: SUBTITLE,\n clickable: () => {\n this.slider.createTab(AppPrivacyForwardMessagesTab).open();\n },\n listenerSetter: this.listenerSetter\n });\n\n const groupChatsAddRow = rowsByKeys['inputPrivacyKeyChatInvite'] = new Row({\n titleLangKey: 'WhoCanAddMe',\n subtitleLangKey: SUBTITLE,\n clickable: () => {\n this.slider.createTab(AppPrivacyAddToGroupsTab).open();\n },\n listenerSetter: this.listenerSetter\n });\n\n const voicesRow = rowsByKeys['inputPrivacyKeyVoiceMessages'] = new Row({\n titleLangKey: 'PrivacyVoiceMessagesTitle',\n subtitleLangKey: SUBTITLE,\n clickable: () => {\n if(!rootScope.premium) {\n toastNew({langPackKey: 'PrivacyVoiceMessagesPremiumOnly'});\n } else {\n this.slider.createTab(AppPrivacyVoicesTab).open();\n }\n },\n listenerSetter: this.listenerSetter\n });\n\n const updatePrivacyRow = (key: InputPrivacyKey['_']) => {\n const row = rowsByKeys[key];\n if(!row) {\n return;\n }\n\n this.managers.appPrivacyManager.getPrivacy(key).then((rules) => {\n const details = getPrivacyRulesDetails(rules);\n const langKey = details.type === PrivacyType.Everybody ? 'PrivacySettingsController.Everbody' : (details.type === PrivacyType.Contacts ? 'PrivacySettingsController.MyContacts' : 'PrivacySettingsController.Nobody');\n const disallowLength = details.disallowPeers.users.length + details.disallowPeers.chats.length;\n const allowLength = details.allowPeers.users.length + details.allowPeers.chats.length;\n\n const s = i18n(langKey);\n row.subtitle.replaceChildren(s);\n if(disallowLength || allowLength) {\n row.subtitle.append(` (${[-disallowLength, allowLength ? '+' + allowLength : 0].filter(Boolean).join(', ')})`);\n }\n });\n };\n\n section.content.append(\n numberVisibilityRow.container,\n lastSeenTimeRow.container,\n photoVisibilityRow.container,\n callRow.container,\n linkAccountRow.container,\n groupChatsAddRow.container,\n voicesRow.container\n );\n this.scrollable.append(section.container);\n\n for(const key in rowsByKeys) {\n updatePrivacyRow(key as keyof typeof rowsByKeys);\n }\n\n rootScope.addEventListener('privacy_update', (update) => {\n updatePrivacyRow(convertKeyToInputKey(update.key._) as any);\n });\n }\n\n {\n const section = new SettingSection({name: 'NewChatsFromNonContacts', caption: 'ArchiveAndMuteInfo'});\n\n const checkboxField = new CheckboxField({text: 'ArchiveAndMute'});\n const row = new Row({\n checkboxField\n });\n\n section.content.append(row.container);\n\n let enabled: boolean, destroyed: boolean;\n this.eventListener.addEventListener('destroy', () => {\n destroyed = true;\n if(enabled === undefined || enabled === checkboxField.checked) return;\n return this.managers.appPrivacyManager.setGlobalPrivacySettings({\n _: 'globalPrivacySettings',\n archive_and_mute_new_noncontact_peers: checkboxField.checked\n });\n }, {once: true});\n\n const promise = Promise.all([\n p.appConfig,\n p.globalPrivacy\n ]).then(([appConfig, settings]) => {\n if(destroyed) {\n return;\n }\n\n const onPremiumToggle = (isPremium: boolean) => {\n section.container.classList.toggle('hide', !isPremium && !appConfig.autoarchive_setting_available);\n };\n\n this.listenerSetter.add(rootScope)('premium_toggle', onPremiumToggle);\n onPremiumToggle(rootScope.premium);\n\n enabled = !!settings.archive_and_mute_new_noncontact_peers;\n\n checkboxField.setValueSilently(enabled);\n });\n\n promises.push(promise);\n\n this.scrollable.append(section.container);\n }\n\n {\n const section = new SettingSection({name: 'Privacy.SensitiveContent', caption: 'PrivacyAndSecurity.SensitiveDesc'});\n section.container.classList.add('hide');\n\n const checkboxField = new CheckboxField({text: 'PrivacyAndSecurity.SensitiveText'});\n const row = new Row({\n checkboxField\n });\n\n section.content.append(row.container);\n\n let enabled: boolean;\n this.eventListener.addEventListener('destroy', () => {\n if(enabled === undefined) return;\n const _enabled = row.checkboxField.checked;\n const isChanged = _enabled !== enabled;\n if(!isChanged) {\n return;\n }\n\n return this.managers.apiManager.invokeApi('account.setContentSettings', {\n sensitive_enabled: _enabled\n });\n }, {once: true});\n\n const promise = p.contentSettings.then((settings) => {\n if(!settings.pFlags.sensitive_can_change) {\n return;\n }\n\n enabled = !!settings.pFlags.sensitive_enabled;\n checkboxField.setValueSilently(enabled);\n section.container.classList.remove('hide');\n });\n\n promises.push(promise);\n\n this.scrollable.append(section.container);\n }\n\n {\n const section = new SettingSection({name: 'PrivacyPayments', caption: 'PrivacyPaymentsClearInfo'});\n\n const onClearClick = () => {\n const options: PopupConfirmationOptions = {\n titleLangKey: 'PrivacyPaymentsClearAlertTitle',\n descriptionLangKey: 'PrivacyPaymentsClearAlertText',\n button: {\n langKey: 'Clear'\n },\n checkboxes: [{\n text: 'PrivacyClearShipping',\n checked: true\n }, {\n text: 'PrivacyClearPayment',\n checked: true\n }]\n };\n\n confirmationPopup(options).then(() => {\n const [info, payment] = options.checkboxes.map((c) => c.checkboxField.checked);\n const toggle = toggleDisability([clearButton], true);\n this.managers.appPaymentsManager.clearSavedInfo(info, payment).then(() => {\n if(!info && !payment) {\n return;\n }\n\n toggle();\n toastNew({\n langPackKey: info && payment ? 'PrivacyPaymentsPaymentShippingCleared' : (info ? 'PrivacyPaymentsShippingInfoCleared' : 'PrivacyPaymentsPaymentInfoCleared')\n });\n });\n }, noop);\n };\n\n const clearButton = Button('btn-primary btn-transparent', {icon: 'delete', text: 'PrivacyPaymentsClear'});\n this.listenerSetter.add(clearButton)('click', onClearClick);\n section.content.append(clearButton);\n\n this.scrollable.append(section.container);\n }\n\n {\n const section = new SettingSection({name: 'FilterChats'});\n\n const onDeleteClick = () => {\n const popup = PopupElement.createPopup(PopupPeer, 'popup-delete-drafts', {\n buttons: [{\n langKey: 'Delete',\n callback: () => {\n const toggle = toggleDisability([deleteButton], true);\n this.managers.appDraftsManager.clearAllDrafts().then(() => {\n toggle();\n });\n },\n isDanger: true\n }],\n titleLangKey: 'AreYouSureClearDraftsTitle',\n descriptionLangKey: 'AreYouSureClearDrafts'\n });\n\n popup.show();\n };\n\n const deleteButton = Button('btn-primary btn-transparent', {icon: 'delete', text: 'PrivacyDeleteCloudDrafts'});\n this.listenerSetter.add(deleteButton)('click', onDeleteClick);\n section.content.append(deleteButton);\n\n /* promises.push(apiManager.invokeApi('messages.getAllDrafts').then((drafts) => {\n const draftsRow = new Row({\n titleLangKey: 'PrivacyDeleteCloudDrafts',\n subtitleLangKey: 'Drafts',\n subtitleLangArgs: [(drafts as Updates.updates).updates.length],\n icon: 'delete',\n clickable: onDeleteClick\n });\n\n section.content.append(draftsRow.container);\n })); */\n\n this.scrollable.append(section.container);\n }\n\n // {\n // const section = new SettingSection({\n // name: 'OtherWebSessions'\n // });\n\n // const row = new Row({\n\n // });\n\n // this.scrollable.append(section.container);\n // }\n\n return Promise.all(promises);\n }\n\n public updateActiveSessions() {\n return this.managers.apiManager.invokeApi('account.getAuthorizations').then((auths) => {\n this.activeSessionsRow.freezed = false;\n this.authorizations = auths.authorizations;\n _i18n(this.activeSessionsRow.subtitle, 'Privacy.Devices', [this.authorizations.length]);\n });\n }\n\n public updateActiveWebsites(promise = this.managers.appSeamlessLoginManager.getWebAuthorizations()) {\n return promise.then((authorizations) => {\n this.websitesRow.freezed = false;\n this.websites = authorizations;\n _i18n(this.websitesRow.subtitle, 'Privacy.Websites', [this.websites.length]);\n this.websitesRow.container.classList.toggle('hide', !this.websites.length);\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {State} from '../../../config/state';\nimport flatten from '../../../helpers/array/flatten';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport {LiteModeKey} from '../../../helpers/liteMode';\nimport pause from '../../../helpers/schedulers/pause';\nimport rootScope from '../../../lib/rootScope';\nimport CheckboxFields, {CheckboxFieldsField} from '../../checkboxFields';\nimport SettingSection from '../../settingSection';\nimport SliderSuperTab from '../../sliderTab';\nimport {toastNew} from '../../toast';\n\ntype PowerSavingCheckboxFieldsField = CheckboxFieldsField & {\n key: LiteModeKey\n};\n\nexport default class AppPowerSavingTab extends SliderSuperTab {\n public init() {\n this.container.classList.add('power-saving-container');\n this.setTitle('LiteMode.Title');\n\n const form = document.createElement('form');\n\n let infoSection: SettingSection;\n {\n const section = infoSection = new SettingSection({\n caption: 'LiteMode.Info'\n });\n\n form.append(section.container);\n }\n\n const keys: Array<LiteModeKey | [LiteModeKey, LiteModeKey[]]> = [\n 'all',\n 'video',\n 'gif',\n ['stickers', ['stickers_panel', 'stickers_chat']],\n // ['emoji', ['emoji_panel', 'emoji_messages']],\n ['effects', ['effects_reactions', 'effects_premiumstickers', 'effects_emoji']],\n ['chat', ['chat_background', 'chat_spoilers']],\n 'animations'\n ];\n\n let fields: PowerSavingCheckboxFieldsField[], checkboxFields: CheckboxFields<PowerSavingCheckboxFieldsField>;\n {\n const section = new SettingSection({});\n\n const wrap = (key: typeof keys[0]): PowerSavingCheckboxFieldsField[] => {\n const isArray = Array.isArray(key);\n const mainKey = isArray ? key[0] : key;\n const nested = isArray ? flatten(key[1].map(wrap)) : undefined;\n const value = rootScope.settings.liteMode[mainKey];\n return [{\n key: mainKey,\n text: mainKey === 'all' ? 'LiteMode.EnableText' : `LiteMode.Key.${mainKey}.Title`,\n checked: mainKey === 'all' ? value : !value,\n nested: nested,\n name: 'power-saving-' + mainKey\n }, ...(nested || [])];\n };\n\n fields = flatten(keys.map(wrap));\n\n checkboxFields = new CheckboxFields({\n fields: fields,\n listenerSetter: this.listenerSetter\n });\n\n fields.forEach((field, idx) => {\n const created = checkboxFields.createField(field);\n if(!created) {\n return;\n }\n\n const {row, nodes} = created;\n (idx === 0 ? infoSection : section).content.append(...nodes);\n });\n\n attachClickEvent(section.content, () => {\n if(rootScope.settings.liteMode.all) {\n toastNew({langPackKey: 'LiteMode.DisableAlert'});\n }\n }, {listenerSetter: this.listenerSetter});\n\n form.append(section.container);\n }\n\n const onAllChange = (disable: boolean) => {\n fields.forEach((field) => {\n if(field.key === 'all') {\n return;\n }\n\n if(field.nested) {\n checkboxFields.setNestedCounter(field, disable ? 0 : undefined);\n }\n\n field.checkboxField.input.classList.toggle('is-fake-disabled', disable);\n field.row.toggleDisability(disable);\n });\n };\n\n this.listenerSetter.add(form)('change', async() => {\n const liteMode: State['settings']['liteMode'] = {} as any;\n fields.forEach((field) => {\n const checked = field.checkboxField.checked;\n liteMode[field.key] = field.key === 'all' ? checked : !checked;\n });\n\n const wasAll = rootScope.settings.liteMode.all;\n if(wasAll !== liteMode.all) {\n onAllChange(!wasAll);\n\n if(liteMode.all) {\n await pause(200);\n }\n }\n\n await this.managers.appStateManager.setByKey('settings.liteMode', rootScope.settings.liteMode = liteMode);\n });\n\n onAllChange(rootScope.settings.liteMode.all);\n\n this.scrollable.append(form);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport RangeSelector from '../../rangeSelector';\nimport Button from '../../button';\nimport CheckboxField from '../../checkboxField';\nimport RadioField from '../../radioField';\nimport rootScope from '../../../lib/rootScope';\nimport {IS_APPLE, IS_SAFARI} from '../../../environment/userAgent';\nimport Row from '../../row';\nimport AppBackgroundTab from './background';\nimport I18n, {LangPackKey, _i18n} from '../../../lib/langPack';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport {BaseTheme} from '../../../layer';\nimport eachMinute from '../../../helpers/eachMinute';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport IS_GEOLOCATION_SUPPORTED from '../../../environment/geolocationSupport';\nimport {DEFAULT_THEME, State} from '../../../config/state';\nimport {generateSection} from '../../settingSection';\nimport {ScrollableX} from '../../scrollable';\nimport wrapStickerEmoji from '../../wrappers/stickerEmoji';\nimport {Theme} from '../../../layer';\nimport findUpClassName from '../../../helpers/dom/findUpClassName';\nimport RLottiePlayer from '../../../lib/rlottie/rlottiePlayer';\nimport themeController from '../../../helpers/themeController';\nimport liteMode from '../../../helpers/liteMode';\nimport AppPowerSavingTab from './powerSaving';\nimport {toastNew} from '../../toast';\n\nexport class RangeSettingSelector {\n public container: HTMLDivElement;\n public valueContainer: HTMLElement;\n private range: RangeSelector;\n\n public onChange: (value: number) => void;\n\n constructor(\n name: LangPackKey,\n step: number,\n initialValue: number,\n minValue: number,\n maxValue: number,\n writeValue = true\n ) {\n const BASE_CLASS = 'range-setting-selector';\n this.container = document.createElement('div');\n this.container.classList.add(BASE_CLASS);\n\n const details = document.createElement('div');\n details.classList.add(BASE_CLASS + '-details');\n\n const nameDiv = document.createElement('div');\n nameDiv.classList.add(BASE_CLASS + '-name');\n _i18n(nameDiv, name);\n\n const valueDiv = this.valueContainer = document.createElement('div');\n valueDiv.classList.add(BASE_CLASS + '-value');\n\n if(writeValue) {\n valueDiv.innerHTML = '' + initialValue;\n }\n\n details.append(nameDiv, valueDiv);\n\n this.range = new RangeSelector({\n step,\n min: minValue,\n max: maxValue\n }, initialValue);\n this.range.setListeners();\n this.range.setHandlers({\n onScrub: value => {\n if(this.onChange) {\n this.onChange(value);\n }\n\n if(writeValue) {\n // console.log('font size scrub:', value);\n valueDiv.innerText = '' + value;\n }\n }\n });\n\n this.container.append(details, this.range.container);\n }\n}\n\nexport default class AppGeneralSettingsTab extends SliderSuperTabEventable {\n public static getInitArgs() {\n return {\n themes: rootScope.managers.appThemesManager.getThemes()\n };\n }\n\n public init(p: ReturnType<typeof AppGeneralSettingsTab['getInitArgs']>) {\n this.container.classList.add('general-settings-container');\n this.setTitle('General');\n\n const section = generateSection.bind(null, this.scrollable);\n const promises: Promise<any>[] = [];\n\n {\n const container = section('Settings');\n\n const range = new RangeSettingSelector('TextSize', 1, rootScope.settings.messagesTextSize, 12, 20);\n range.onChange = (value) => {\n rootScope.managers.appStateManager.setByKey('settings.messagesTextSize', value);\n };\n\n const chatBackgroundButton = Button('btn-primary btn-transparent', {icon: 'image', text: 'ChatBackground'});\n\n const initArgs = AppBackgroundTab.getInitArgs();\n attachClickEvent(chatBackgroundButton, () => {\n this.slider.createTab(AppBackgroundTab).open(initArgs);\n });\n\n const getLiteModeStatus = (): LangPackKey => rootScope.settings.liteMode.all ? 'Checkbox.Enabled' : 'Checkbox.Disabled';\n const i = new I18n.IntlElement();\n\n const onUpdate = () => {\n i.compareAndUpdate({key: getLiteModeStatus()});\n animationsCheckboxField.setValueSilently(liteMode.isAvailable('animations'));\n animationsCheckboxField.toggleDisability(liteMode.isEnabled());\n };\n\n const animationsCheckboxField = new CheckboxField({\n text: 'EnableAnimations',\n name: 'animations',\n stateKey: 'settings.liteMode.animations',\n stateValueReverse: true,\n checked: false,\n listenerSetter: this.listenerSetter\n });\n\n const animationsRow = new Row({\n checkboxField: animationsCheckboxField,\n clickable: () => {\n if(animationsCheckboxField.isDisabled()) {\n toastNew({langPackKey: 'LiteMode.DisableAlert'});\n }\n },\n listenerSetter: this.listenerSetter\n });\n\n const liteModeRow = new Row({\n icon: 'animations',\n titleLangKey: 'LiteMode.EnableText',\n titleRightSecondary: i.element,\n clickable: () => {\n this.slider.createTab(AppPowerSavingTab).open();\n },\n listenerSetter: this.listenerSetter\n });\n\n onUpdate();\n\n this.listenerSetter.add(rootScope)('settings_updated', onUpdate);\n\n container.append(\n range.container,\n chatBackgroundButton,\n animationsRow.container,\n liteModeRow.container\n );\n }\n\n {\n const container = section('ColorTheme');\n\n const scrollable = new ScrollableX(null);\n const themesContainer = scrollable.container;\n themesContainer.classList.add('themes-container');\n\n type K = {\n container: HTMLElement,\n theme: Theme,\n player?: RLottiePlayer,\n wallPaperContainers?: {[key in BaseTheme['_']]?: HTMLElement}\n };\n const themesMap = new Map<HTMLElement, K>();\n let currentTheme = themeController.getTheme();\n let isNight = themeController.isNight();\n\n const applyThemeOnItem = (item: K) => {\n themeController.applyTheme(item.theme, item.container);\n\n const previous = item.container.querySelector('.background-item');\n previous?.remove();\n\n const wallPaperContainer = item.wallPaperContainers[isNight ? 'baseThemeNight' : 'baseThemeClassic']\n if(wallPaperContainer) {\n item.container.prepend(wallPaperContainer);\n }\n };\n\n let lastOnFrameNo: (frameNo: number) => void;\n\n attachClickEvent(themesContainer, async(e) => {\n const container = findUpClassName(e.target, 'theme-container');\n if(!container) {\n return;\n }\n\n const lastActive = themesContainer.querySelector('.active');\n if(lastActive) {\n lastActive.classList.remove('active');\n }\n\n const item = themesMap.get(container);\n container.classList.add('active');\n\n await themeController.applyNewTheme(item.theme);\n\n lastOnFrameNo?.(-1);\n\n if(item.player && liteMode.isAvailable('animations')) {\n if(IS_SAFARI) {\n if(item.player.paused) {\n item.player.restart();\n }\n } else {\n if(item.player.paused) {\n item.player.stop(true);\n }\n\n item.player.el[0].style.transform = 'scale(2)';\n\n const onFrameNo = lastOnFrameNo = (frameNo) => {\n if(item.player.maxFrame === frameNo || frameNo === -1) {\n item.player.el[0].style.transform = '';\n item.player.removeEventListener('enterFrame', onFrameNo);\n\n if(lastOnFrameNo === onFrameNo) {\n lastOnFrameNo = undefined;\n }\n }\n };\n\n setTimeout(() => {\n if(lastOnFrameNo !== onFrameNo) {\n return;\n }\n\n item.player.play();\n item.player.addEventListener('enterFrame', onFrameNo);\n }, 250);\n }\n }\n }, {listenerSetter: this.listenerSetter});\n\n const availableBaseThemes: Set<BaseTheme['_']> = new Set(['baseThemeClassic', 'baseThemeNight']);\n\n const promise = p.themes.then(async(themes) => {\n const defaultThemes = themes.filter((theme) => theme.pFlags.default/* && theme.settings[0].message_colors.length === 1 */);\n defaultThemes.unshift(DEFAULT_THEME);\n\n const promises = defaultThemes.map(async(theme) => {\n const container = document.createElement('div');\n const k: K = {\n container,\n theme,\n wallPaperContainers: {}\n };\n\n const results = theme.settings\n .filter((themeSettings) => availableBaseThemes.has(themeSettings.base_theme._))\n .map((themeSettings) => {\n const wallPaper = themeSettings.wallpaper;\n const result = AppBackgroundTab.addWallPaper(wallPaper);\n k.wallPaperContainers[themeSettings.base_theme._] = result.container;\n return result;\n });\n\n themesMap.set(container, k);\n\n applyThemeOnItem(k);\n\n if(theme.id === currentTheme.id) {\n container.classList.add('active');\n }\n\n const emoticon = theme.emoticon;\n const loadPromises: Promise<any>[] = [];\n let emoticonContainer: HTMLElement;\n if(emoticon) {\n emoticonContainer = document.createElement('div');\n emoticonContainer.classList.add('theme-emoticon');\n const size = 28 * 1.75;\n wrapStickerEmoji({\n div: emoticonContainer,\n width: size,\n height: size,\n emoji: theme.emoticon,\n managers: this.managers,\n loadPromises,\n middleware: this.middlewareHelper.get(),\n play: false\n }).then(({render}) => render).then((player) => {\n k.player = player as RLottiePlayer;\n });\n }\n\n const bubble = document.createElement('div');\n bubble.classList.add('theme-bubble');\n\n const bubbleIn = bubble.cloneNode() as HTMLElement;\n\n bubbleIn.classList.add('is-in');\n bubble.classList.add('is-out');\n\n loadPromises.push(...results.map((result) => result.loadPromise));\n\n container.classList.add('theme-container');\n\n await Promise.all(loadPromises);\n\n if(emoticonContainer) {\n container.append(emoticonContainer);\n }\n\n container.append(bubbleIn, bubble);\n\n return container;\n });\n\n const containers = await Promise.all(promises);\n\n scrollable.append(...containers);\n });\n\n promises.push(promise);\n\n const form = document.createElement('form');\n form.style.marginTop = '.5rem';\n\n const name = 'theme';\n const stateKey = 'settings.theme';\n\n const dayRow = new Row({\n radioField: new RadioField({\n langKey: 'ThemeDay',\n name,\n value: 'day',\n stateKey\n })\n });\n\n const nightRow = new Row({\n radioField: new RadioField({\n langKey: 'ThemeNight',\n name,\n value: 'night',\n stateKey\n })\n });\n\n const systemRow = new Row({\n radioField: new RadioField({\n langKey: 'AutoNightSystemDefault',\n name,\n value: 'system',\n stateKey\n })\n });\n\n this.listenerSetter.add(rootScope)('settings_updated', ({key, value, settings}) => {\n if(key === stateKey) {\n rootScope.dispatchEvent('theme_change');\n }\n });\n\n this.listenerSetter.add(rootScope)('theme_change', () => {\n currentTheme = themeController.getTheme();\n const newIsNight = themeController.isNight();\n if(isNight === newIsNight) {\n return;\n }\n\n isNight = newIsNight;\n\n const lastActive = themesContainer.querySelector('.active');\n if(lastActive) {\n lastActive.classList.remove('active');\n }\n\n let active: HTMLElement;\n themesMap.forEach((item) => {\n applyThemeOnItem(item);\n\n if(item.theme.id === currentTheme.id) {\n item.container.classList.add('active');\n active = item.container;\n }\n });\n\n if(active) {\n scrollable.scrollIntoViewNew({\n element: active,\n position: 'center',\n axis: 'x'\n });\n }\n });\n\n form.append(dayRow.container, nightRow.container, systemRow.container);\n\n container.append(\n themesContainer,\n form\n );\n }\n\n {\n const container = section('General.Keyboard');\n\n const form = document.createElement('form');\n\n const name = 'send-shortcut';\n const stateKey = 'settings.sendShortcut';\n\n const enterRow = new Row({\n radioField: new RadioField({\n langKey: 'General.SendShortcut.Enter',\n name,\n value: 'enter',\n stateKey\n }),\n subtitleLangKey: 'General.SendShortcut.NewLine.ShiftEnter'\n });\n\n const ctrlEnterRow = new Row({\n radioField: new RadioField({\n name,\n value: 'ctrlEnter',\n stateKey\n }),\n subtitleLangKey: 'General.SendShortcut.NewLine.Enter'\n });\n _i18n(ctrlEnterRow.radioField.main, 'General.SendShortcut.CtrlEnter', [IS_APPLE ? '⌘' : 'Ctrl']);\n\n form.append(enterRow.container, ctrlEnterRow.container);\n container.append(form);\n }\n\n if(IS_GEOLOCATION_SUPPORTED) {\n const container = section('DistanceUnitsTitle');\n\n const form = document.createElement('form');\n\n const name = 'distance-unit';\n const stateKey = 'settings.distanceUnit';\n\n const kilometersRow = new Row({\n radioField: new RadioField({\n langKey: 'DistanceUnitsKilometers',\n name,\n value: 'kilometers',\n stateKey\n })\n });\n\n const milesRow = new Row({\n radioField: new RadioField({\n langKey: 'DistanceUnitsMiles',\n name,\n value: 'miles',\n stateKey\n })\n });\n\n form.append(kilometersRow.container, milesRow.container);\n container.append(form);\n }\n\n {\n const container = section('General.TimeFormat');\n\n const form = document.createElement('form');\n\n const name = 'time-format';\n const stateKey = 'settings.timeFormat';\n\n const formats: [State['settings']['timeFormat'], LangPackKey][] = [\n ['h12', 'General.TimeFormat.h12'],\n ['h23', 'General.TimeFormat.h23']\n ];\n\n const rows = formats.map(([format, langPackKey]) => {\n const row = new Row({\n radioField: new RadioField({\n langKey: langPackKey,\n name,\n value: format,\n stateKey\n })\n });\n\n return row;\n });\n\n const cancel = eachMinute(() => {\n const date = new Date();\n\n formats.forEach(([format], idx) => {\n const str = date.toLocaleTimeString('en-us-u-hc-' + format, {\n hour: '2-digit',\n minute: '2-digit'\n });\n\n rows[idx].subtitle.textContent = str;\n });\n });\n\n this.eventListener.addEventListener('destroy', cancel);\n\n form.append(...rows.map((row) => row.container));\n container.append(form);\n }\n\n return Promise.all(promises);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport eachTimeout from './eachTimeout';\n\n// It's better to use timeout instead of interval, because interval can be corrupted\nexport default function eachMinute(callback: () => any, runFirst = true) {\n return eachTimeout(callback, () => (60 - new Date().getSeconds()) * 1000, runFirst);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport ctx from '../environment/ctx';\nimport noop from './noop';\n\n// It's better to use timeout instead of interval, because interval can be corrupted\nexport default function eachTimeout(callback: () => any, getNextTimeout: () => number, runFirst = true) {\n const cancel = () => {\n clearTimeout(timeout);\n };\n\n // replace callback to run noop and restore after\n const _callback = callback;\n if(!runFirst) {\n callback = noop;\n }\n\n let timeout: number;\n (function run() {\n callback();\n timeout = ctx.setTimeout(run, getNextTimeout());\n })();\n\n callback = _callback;\n\n return cancel;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDialogFilter} from '../../../lib/storages/filters';\nimport type {DialogFilterSuggested} from '../../../layer';\nimport type _rootScope from '../../../lib/rootScope';\nimport {SliderSuperTab} from '../../slider';\nimport lottieLoader, {LottieLoader} from '../../../lib/rlottie/lottieLoader';\nimport Button from '../../button';\nimport rootScope from '../../../lib/rootScope';\nimport AppEditFolderTab from './editFolder';\nimport Row from '../../row';\nimport {i18n, i18n_, LangPackKey, join} from '../../../lib/langPack';\nimport cancelEvent from '../../../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport positionElementByIndex from '../../../helpers/dom/positionElementByIndex';\nimport RLottiePlayer from '../../../lib/rlottie/rlottiePlayer';\nimport wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';\nimport {FOLDER_ID_ALL, FOLDER_ID_ARCHIVE, REAL_FOLDERS} from '../../../lib/mtproto/mtproto_config';\nimport replaceContent from '../../../helpers/dom/replaceContent';\nimport SettingSection from '../../settingSection';\nimport Sortable from '../../../helpers/dom/sortable';\nimport whichChild from '../../../helpers/dom/whichChild';\nimport indexOfAndSplice from '../../../helpers/array/indexOfAndSplice';\nimport showLimitPopup from '../../popups/limit';\n\nexport default class AppChatFoldersTab extends SliderSuperTab {\n private createFolderBtn: HTMLElement;\n private foldersSection: SettingSection;\n private suggestedSection: SettingSection;\n private stickerContainer: HTMLElement;\n private animation: RLottiePlayer;\n private list: HTMLElement;\n\n private filtersRendered: {[filterId: number]: Row} = {};\n private loadAnimationPromise: ReturnType<LottieLoader['waitForFirstFrame']>;\n\n public static getInitArgs() {\n return {\n animationData: lottieLoader.loadAnimationFromURLManually('Folders_1'),\n filters: rootScope.managers.filtersStorage.getDialogFilters()\n };\n }\n\n private async renderFolder(\n dialogFilter: DialogFilterSuggested | MyDialogFilter,\n container?: HTMLElement,\n row?: Row,\n append?: boolean\n ) {\n let filter: MyDialogFilter;\n let description = '';\n const d: HTMLElement[] = [];\n if(dialogFilter._ === 'dialogFilterSuggested') {\n filter = dialogFilter.filter as MyDialogFilter;\n description = dialogFilter.description;\n } else {\n filter = dialogFilter;\n\n const enabledFilters = Object.keys(filter.pFlags).length;\n /* (['include_peers', 'exclude_peers'] as ['include_peers', 'exclude_peers']).forEach((key) => {\n enabledFilters += +!!filter[key].length;\n }); */\n\n if(enabledFilters === 1) {\n const pFlags = filter.pFlags;\n let k: LangPackKey;\n if(pFlags.contacts) k = 'FilterAllContacts';\n else if(pFlags.non_contacts) k = 'FilterAllNonContacts';\n else if(pFlags.groups) k = 'FilterAllGroups';\n else if(pFlags.broadcasts) k = 'FilterAllChannels';\n else if(pFlags.bots) k = 'FilterAllBots';\n\n if(k) {\n d.push(i18n(k));\n }\n }\n\n if(!d.length) {\n const folder = await this.managers.dialogsStorage.getFolderDialogs(filter.id);\n let chats = 0, channels = 0, groups = 0;\n await Promise.all(folder.map(async(dialog) => {\n if(await this.managers.appPeersManager.isAnyGroup(dialog.peerId)) groups++;\n else if(await this.managers.appPeersManager.isBroadcast(dialog.peerId)) channels++;\n else chats++;\n }));\n\n if(chats) d.push(i18n('Chats', [chats]));\n if(channels) d.push(i18n('Channels', [channels]));\n if(groups) d.push(i18n('Groups', [groups]));\n }\n }\n\n if(!row) {\n row = new Row({\n title: filter.id === FOLDER_ID_ALL ? i18n('FilterAllChats') : wrapEmojiText(filter.title),\n subtitle: description,\n clickable: true,\n buttonRightLangKey: dialogFilter._ === 'dialogFilterSuggested' ? 'Add' : undefined\n });\n\n if(d.length) {\n row.subtitle.append(...join(d));\n }\n\n if(dialogFilter._ === 'dialogFilter') {\n const filterId = filter.id;\n if(!this.filtersRendered[filter.id] && filter.id !== FOLDER_ID_ALL) {\n const initArgs = AppEditFolderTab.getInitArgs();\n attachClickEvent(row.container, async() => {\n const filter = await this.managers.filtersStorage.getFilter(filterId);\n const tab = this.slider.createTab(AppEditFolderTab);\n tab.setInitFilter(filter);\n tab.open(initArgs);\n }, {listenerSetter: this.listenerSetter});\n }\n\n this.filtersRendered[filter.id] = row;\n\n row.makeSortable();\n }\n } else {\n if(filter.id !== FOLDER_ID_ALL) {\n replaceContent(row.title, wrapEmojiText(filter.title));\n }\n\n row.subtitle.textContent = '';\n row.subtitle.append(...join(d));\n }\n\n const div = row.container;\n\n if(append) {\n const localId = (filter as MyDialogFilter).localId;\n if(localId !== undefined) {\n // ! header will be at 0 index\n positionElementByIndex(div, div.parentElement || container, localId);\n } else if(container) {\n container.append(div);\n }\n }\n\n return row;\n }\n\n public init(p: ReturnType<typeof AppChatFoldersTab['getInitArgs']> = AppChatFoldersTab.getInitArgs()) {\n this.container.classList.add('chat-folders-container');\n this.setTitle('ChatList.Filter.List.Title');\n\n this.scrollable.container.classList.add('chat-folders');\n\n this.stickerContainer = document.createElement('div');\n this.stickerContainer.classList.add('sticker-container');\n\n const caption = document.createElement('div');\n caption.classList.add('caption');\n i18n_({element: caption, key: 'ChatList.Filter.Header'});\n\n this.createFolderBtn = Button('btn-primary btn-color-primary btn-control tgico', {\n text: 'ChatList.Filter.NewTitle',\n icon: 'add'\n });\n\n this.foldersSection = new SettingSection({\n name: 'Filters'\n });\n this.foldersSection.container.classList.add('hide');\n\n this.list = document.createElement('div');\n this.foldersSection.content.append(this.list);\n\n this.suggestedSection = new SettingSection({\n name: 'FilterRecommended'\n });\n this.suggestedSection.container.classList.add('hide');\n\n this.scrollable.append(\n this.stickerContainer,\n caption,\n this.createFolderBtn,\n this.foldersSection.container,\n this.suggestedSection.container\n );\n\n attachClickEvent(this.createFolderBtn, async() => {\n if(!(await this.canCreateFolder())) {\n showLimitPopup('folders');\n } else {\n this.slider.createTab(AppEditFolderTab).open();\n }\n }, {listenerSetter: this.listenerSetter});\n\n const onFiltersContainerUpdate = () => {\n this.foldersSection.container.classList.toggle('hide', !Object.keys(this.filtersRendered).length);\n };\n\n const loadPromises: Promise<any>[] = [];\n const renderFiltersPromise = p.filters.then(async(filters) => {\n for(const filter of filters) {\n if(filter.id === FOLDER_ID_ARCHIVE) {\n continue;\n }\n\n await this.renderFolder(filter, this.list, undefined, true);\n }\n\n this.toggleAllChats();\n\n onFiltersContainerUpdate();\n });\n\n loadPromises.push(renderFiltersPromise);\n\n this.listenerSetter.add(rootScope)('filter_update', async(filter) => {\n const filterRendered = this.filtersRendered[filter.id];\n if(filterRendered) {\n await this.renderFolder(filter, null, filterRendered);\n } else if(filter.id !== FOLDER_ID_ARCHIVE) {\n await this.renderFolder(filter, this.list, undefined, true);\n }\n\n onFiltersContainerUpdate();\n\n this.getSuggestedFilters();\n });\n\n this.listenerSetter.add(rootScope)('filter_delete', (filter) => {\n const filterRendered = this.filtersRendered[filter.id];\n if(filterRendered) {\n /* for(const suggested of this.suggestedFilters) {\n if(deepEqual(suggested.filter, filter)) {\n\n }\n } */\n this.getSuggestedFilters();\n\n filterRendered.container.remove();\n delete this.filtersRendered[filter.id];\n }\n\n onFiltersContainerUpdate();\n });\n\n this.listenerSetter.add(rootScope)('filter_order', (order) => {\n order.filter((filterId) => !!this.filtersRendered[filterId]).forEach((filterId, idx) => {\n const filterRendered = this.filtersRendered[filterId];\n const container = filterRendered.container;\n positionElementByIndex(container, container.parentElement, idx + 1); // ! + 1 due to header\n });\n });\n\n this.listenerSetter.add(rootScope)('premium_toggle', () => {\n this.toggleAllChats();\n });\n\n this.loadAnimationPromise = p.animationData.then(async(cb) => {\n const player = await cb({\n container: this.stickerContainer,\n loop: false,\n autoplay: false,\n width: 86,\n height: 86\n });\n\n this.animation = player;\n\n return lottieLoader.waitForFirstFrame(player);\n });\n\n loadPromises.push(this.loadAnimationPromise);\n\n new Sortable({\n list: this.list,\n middleware: this.middlewareHelper.get(),\n onSort: (prevIdx, newIdx) => {\n let order: number[] = [];\n for(const filterId in this.filtersRendered) {\n const row = this.filtersRendered[filterId];\n const idx = whichChild(row.container);\n order[idx] = +filterId;\n }\n\n order = order.filter((filterId) => filterId !== undefined);\n if(!rootScope.premium) {\n indexOfAndSplice(order, FOLDER_ID_ALL);\n // order.unshift(FOLDER_ID_ALL);\n }\n\n this.managers.filtersStorage.updateDialogFiltersOrder(order);\n },\n scrollable: this.scrollable\n });\n\n this.getSuggestedFilters();\n\n /* return Promise.all([\n this.loadAnimationPromise\n ]); */\n return Promise.all(loadPromises);\n }\n\n onOpenAfterTimeout() {\n this.loadAnimationPromise.then(() => {\n this.animation.autoplay = true;\n this.animation.play();\n });\n\n return super.onOpenAfterTimeout();\n }\n\n private toggleAllChats() {\n const filterRendered = this.filtersRendered[FOLDER_ID_ALL];\n filterRendered.container.classList.toggle('hide', !rootScope.premium);\n }\n\n private async canCreateFolder() {\n const [limit, filters] = await Promise.all([\n this.managers.apiManager.getLimit('folders'),\n this.managers.filtersStorage.getDialogFilters()\n ]);\n\n const filtersLength = filters.filter((filter) => !REAL_FOLDERS.has(filter.id)).length;\n return filtersLength < limit;\n }\n\n private getSuggestedFilters() {\n return this.managers.filtersStorage.getSuggestedDialogsFilters().then(async(suggestedFilters) => {\n this.suggestedSection.container.classList.toggle('hide', !suggestedFilters.length);\n Array.from(this.suggestedSection.content.children).slice(1).forEach((el) => el.remove());\n\n for(const filter of suggestedFilters) {\n const row = await this.renderFolder(filter);\n this.suggestedSection.content.append(row.container);\n\n const button = row.buttonRight;\n attachClickEvent(button, async(e) => {\n cancelEvent(e);\n\n if(!(await this.canCreateFolder())) {\n showLimitPopup('folders');\n return;\n }\n\n button.setAttribute('disabled', 'true');\n\n const f = filter.filter as MyDialogFilter;\n f.includePeerIds = [];\n f.excludePeerIds = [];\n f.pinnedPeerIds = [];\n\n this.managers.filtersStorage.createDialogFilter(f, true).then(() => {\n row.container.remove();\n this.suggestedSection.container.classList.toggle('hide', this.suggestedSection.content.childElementCount === 1);\n }).finally(() => {\n button.removeAttribute('disabled');\n });\n }, {listenerSetter: this.listenerSetter});\n }\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport Row from '../../row';\nimport CheckboxField from '../../checkboxField';\nimport {InputNotifyPeer, InputPeerNotifySettings, Update} from '../../../layer';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport rootScope from '../../../lib/rootScope';\nimport {LangPackKey} from '../../../lib/langPack';\nimport copy from '../../../helpers/object/copy';\nimport convertKeyToInputKey from '../../../helpers/string/convertKeyToInputKey';\nimport {MUTE_UNTIL} from '../../../lib/mtproto/mtproto_config';\nimport apiManagerProxy from '../../../lib/mtproto/mtprotoworker';\nimport SettingSection from '../../settingSection';\n\ntype InputNotifyKey = Exclude<InputNotifyPeer['_'], 'inputNotifyPeer' | 'inputNotifyForumTopic'>;\n\nexport default class AppNotificationsTab extends SliderSuperTabEventable {\n public init() {\n this.container.classList.add('notifications-container');\n this.setTitle('Telegram.NotificationSettingsViewController');\n\n const NotifySection = (options: {\n name: LangPackKey,\n typeText: LangPackKey,\n inputKey: InputNotifyKey,\n }) => {\n const section = new SettingSection({\n name: options.name\n });\n\n const enabledRow = new Row({\n checkboxField: new CheckboxField({text: options.typeText, checked: true}),\n subtitleLangKey: 'Loading',\n listenerSetter: this.listenerSetter,\n withCheckboxSubtitle: true\n });\n\n const previewEnabledRow = new Row({\n checkboxField: new CheckboxField({text: 'MessagePreview', checked: true}),\n subtitleLangKey: 'Loading',\n listenerSetter: this.listenerSetter,\n withCheckboxSubtitle: true\n });\n\n section.content.append(enabledRow.container, previewEnabledRow.container);\n\n this.scrollable.append(section.container);\n\n const inputNotifyPeer = {_: options.inputKey};\n const ret = this.managers.appNotificationsManager.getNotifySettings(inputNotifyPeer);\n (ret instanceof Promise ? ret : Promise.resolve(ret)).then((notifySettings) => {\n const applySettings = async() => {\n const muted = await this.managers.appNotificationsManager.isMuted(notifySettings);\n enabledRow.checkboxField.checked = !muted;\n previewEnabledRow.checkboxField.checked = notifySettings.show_previews;\n\n return muted;\n };\n\n applySettings();\n\n this.eventListener.addEventListener('destroy', async() => {\n const mute = !enabledRow.checkboxField.checked;\n const showPreviews = previewEnabledRow.checkboxField.checked;\n\n if(mute === (await this.managers.appNotificationsManager.isMuted(notifySettings)) && showPreviews === notifySettings.show_previews) {\n return;\n }\n\n const inputSettings: InputPeerNotifySettings = copy(notifySettings) as any;\n inputSettings._ = 'inputPeerNotifySettings';\n inputSettings.mute_until = mute ? MUTE_UNTIL : 0;\n inputSettings.show_previews = showPreviews;\n delete inputSettings.flags;\n\n this.managers.appNotificationsManager.updateNotifySettings(inputNotifyPeer, inputSettings);\n }, {once: true});\n\n this.listenerSetter.add(rootScope)('notify_settings', (update: Update.updateNotifySettings) => {\n const inputKey = convertKeyToInputKey(update.peer._) as any;\n if(options.inputKey === inputKey) {\n notifySettings = update.notify_settings;\n applySettings();\n }\n });\n });\n };\n\n NotifySection({\n name: 'NotificationsPrivateChats',\n typeText: 'NotificationsForPrivateChats',\n inputKey: 'inputNotifyUsers'\n });\n\n NotifySection({\n name: 'NotificationsGroups',\n typeText: 'NotificationsForGroups',\n inputKey: 'inputNotifyChats'\n });\n\n NotifySection({\n name: 'NotificationsChannels',\n typeText: 'NotificationsForChannels',\n inputKey: 'inputNotifyBroadcasts'\n });\n\n {\n const section = new SettingSection({\n name: 'NotificationsOther'\n });\n\n const contactsSignUpRow = new Row({\n checkboxField: new CheckboxField({text: 'ContactJoined', checked: true}),\n subtitleLangKey: 'Loading',\n listenerSetter: this.listenerSetter,\n withCheckboxSubtitle: true\n });\n\n const soundRow = new Row({\n checkboxField: new CheckboxField({text: 'Notifications.Sound', checked: true, stateKey: 'settings.notifications.sound', listenerSetter: this.listenerSetter}),\n subtitleLangKey: 'Loading',\n listenerSetter: this.listenerSetter,\n withCheckboxSubtitle: true\n });\n\n apiManagerProxy.getState().then((state) => {\n soundRow.checkboxField.checked = state.settings.notifications.sound;\n });\n\n section.content.append(contactsSignUpRow.container, soundRow.container);\n\n this.scrollable.append(section.container);\n\n this.managers.appNotificationsManager.getContactSignUpNotification().then((enabled) => {\n contactsSignUpRow.checkboxField.checked = enabled;\n\n this.eventListener.addEventListener('destroy', () => {\n const _enabled = contactsSignUpRow.checkboxField.checked;\n if(enabled !== _enabled) {\n this.managers.appNotificationsManager.setContactSignUpNotification(!_enabled);\n }\n }, {once: true});\n });\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {randomLong} from '../../../helpers/random';\nimport {LangPackLanguage} from '../../../layer';\nimport I18n from '../../../lib/langPack';\nimport rootScope from '../../../lib/rootScope';\nimport RadioField from '../../radioField';\nimport Row, {RadioFormFromRows} from '../../row';\nimport SettingSection from '../../settingSection';\nimport {SliderSuperTab} from '../../slider'\n\nexport default class AppLanguageTab extends SliderSuperTab {\n public static getInitArgs() {\n return {\n languages1: rootScope.managers.apiManager.invokeApiCacheable('langpack.getLanguages', {\n lang_pack: 'web'\n }),\n // languages2: rootScope.managers.apiManager.invokeApiCacheable('langpack.getLanguages', {\n // lang_pack: 'macos'\n // })\n languages2: Promise.resolve([] as LangPackLanguage[])\n };\n }\n\n public init(p: ReturnType<typeof AppLanguageTab['getInitArgs']>) {\n this.header.classList.add('with-border');\n this.container.classList.add('language-container');\n this.setTitle('Telegram.LanguageViewController');\n\n const section = new SettingSection({});\n\n const radioRows: Map<string, Row> = new Map();\n\n const promise = Promise.all([\n p.languages1,\n p.languages2\n ]).then(([languages1, languages2]) => {\n const rendered: Set<string> = new Set();\n const webLangCodes = languages1.map((language) => language.lang_code);\n\n const random = randomLong();\n languages1.concat(languages2).forEach((language) => {\n if(rendered.has(language.lang_code)) return;\n rendered.add(language.lang_code);\n\n const row = new Row({\n radioField: new RadioField({\n text: language.name,\n name: random,\n value: language.lang_code\n }),\n subtitle: language.native_name\n });\n\n radioRows.set(language.lang_code, row);\n });\n\n const form = RadioFormFromRows([...radioRows.values()], (value) => {\n I18n.getLangPack(value, webLangCodes.includes(value));\n });\n\n I18n.getCacheLangPack().then((langPack) => {\n const row = radioRows.get(langPack.lang_code);\n if(!row) {\n console.error('no row', row, langPack);\n return;\n }\n\n row.radioField.setValueSilently(true);\n });\n\n section.content.append(form);\n });\n\n this.scrollable.append(section.container);\n\n return promise;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ListenerSetter from '../../../../helpers/listenerSetter';\nimport {LangPackKey} from '../../../../lib/langPack';\nimport CheckboxField from '../../../checkboxField';\nimport {SliderSuperTabEventable} from '../../../sliderTab';\nimport Row, {CreateRowFromCheckboxField} from '../../../row';\nimport SettingSection from '../../../settingSection';\n\nexport function autoDownloadPeerTypeSection(type: 'photo' | 'video' | 'file', title: LangPackKey, listenerSetter: ListenerSetter) {\n const section = new SettingSection({name: title});\n\n const key = 'settings.autoDownload.' + type + '.';\n const contactsCheckboxField = new CheckboxField({\n text: 'AutodownloadContacts',\n name: 'contacts',\n stateKey: key + 'contacts',\n listenerSetter\n });\n const privateCheckboxField = new CheckboxField({\n text: 'AutodownloadPrivateChats',\n name: 'private',\n stateKey: key + 'private',\n listenerSetter\n });\n const groupsCheckboxField = new CheckboxField({\n text: 'AutodownloadGroupChats',\n name: 'groups',\n stateKey: key + 'groups',\n listenerSetter\n });\n const channelsCheckboxField = new CheckboxField({\n text: 'AutodownloadChannels',\n name: 'channels',\n stateKey: key + 'channels',\n listenerSetter\n });\n\n section.content.append(\n CreateRowFromCheckboxField(contactsCheckboxField).container,\n CreateRowFromCheckboxField(privateCheckboxField).container,\n CreateRowFromCheckboxField(groupsCheckboxField).container,\n CreateRowFromCheckboxField(channelsCheckboxField).container\n );\n\n return section;\n}\n\nexport default class AppAutoDownloadPhotoTab extends SliderSuperTabEventable {\n public init() {\n this.setTitle('AutoDownloadPhotos');\n\n const section = autoDownloadPeerTypeSection('photo', 'AutoDownloadPhotosTitle', this.listenerSetter);\n this.scrollable.append(section.container);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport formatBytes from '../../../../helpers/formatBytes';\nimport debounce from '../../../../helpers/schedulers/debounce';\nimport I18n from '../../../../lib/langPack';\nimport rootScope from '../../../../lib/rootScope';\nimport {SliderSuperTabEventable} from '../../../sliderTab';\nimport {RangeSettingSelector} from '../generalSettings';\nimport {autoDownloadPeerTypeSection} from './photo';\n\nexport default class AppAutoDownloadFileTab extends SliderSuperTabEventable {\n public init() {\n this.setTitle('AutoDownloadFiles');\n\n const debouncedSave = debounce((sizeMax: number) => {\n this.managers.appStateManager.setByKey('settings.autoDownloadNew.file_size_max', sizeMax);\n }, 200, false, true);\n\n const section = autoDownloadPeerTypeSection('file', 'AutoDownloadFilesTitle', this.listenerSetter);\n\n const MIN = 512 * 1024;\n // const MAX = 2 * 1024 * 1024 * 1024;\n const MAX = 20 * 1024 * 1024;\n const MAX_RANGE = MAX - MIN;\n\n const sizeMax = rootScope.settings.autoDownloadNew.file_size_max;\n const value = Math.sqrt(Math.sqrt((sizeMax - MIN) / MAX_RANGE));\n const upTo = new I18n.IntlElement({\n key: 'AutodownloadSizeLimitUpTo',\n args: [formatBytes(sizeMax)]\n });\n const range = new RangeSettingSelector('AutoDownloadMaxFileSize', 0.01, value, 0, 1, false);\n range.onChange = (value) => {\n const sizeMax = (value ** 4 * MAX_RANGE + MIN) | 0;\n\n upTo.compareAndUpdate({args: [formatBytes(sizeMax)]});\n\n debouncedSave(sizeMax);\n };\n\n range.valueContainer.append(upTo.element);\n\n section.content.append(range.container);\n\n this.scrollable.append(section.container);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTabEventable} from '../../../sliderTab';\nimport {autoDownloadPeerTypeSection} from './photo';\n\nexport default class AppAutoDownloadVideoTab extends SliderSuperTabEventable {\n public init() {\n this.setTitle('AutoDownloadVideos');\n\n const section = autoDownloadPeerTypeSection('video', 'AutoDownloadVideosTitle', this.listenerSetter);\n this.scrollable.append(section.container);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AutoDownloadPeerTypeSettings, STATE_INIT} from '../../../config/state';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport replaceContent from '../../../helpers/dom/replaceContent';\nimport toggleDisability from '../../../helpers/dom/toggleDisability';\nimport formatBytes from '../../../helpers/formatBytes';\nimport copy from '../../../helpers/object/copy';\nimport deepEqual from '../../../helpers/object/deepEqual';\nimport {FormatterArguments, i18n, join, LangPackKey} from '../../../lib/langPack';\nimport rootScope from '../../../lib/rootScope';\nimport Button from '../../button';\nimport CheckboxField from '../../checkboxField';\nimport confirmationPopup from '../../confirmationPopup';\nimport Row from '../../row';\nimport {SliderSuperTabEventable, SliderSuperTabEventableConstructable} from '../../sliderTab';\nimport AppAutoDownloadFileTab from './autoDownload/file';\nimport AppAutoDownloadPhotoTab from './autoDownload/photo';\nimport AppAutoDownloadVideoTab from './autoDownload/video';\nimport SettingSection from '../../settingSection';\n\nconst AUTO_DOWNLOAD_FOR_KEYS: {[k in keyof AutoDownloadPeerTypeSettings]: LangPackKey} = {\n contacts: 'AutoDownloadContacts',\n private: 'AutoDownloadPm',\n groups: 'AutoDownloadGroups',\n channels: 'AutoDownloadChannels'\n};\n\nexport default class AppDataAndStorageTab extends SliderSuperTabEventable {\n public init() {\n this.setTitle('DataSettings');\n\n {\n const section = new SettingSection({name: 'AutomaticMediaDownload', caption: 'AutoDownloadAudioInfo'});\n\n const autoCheckboxField = new CheckboxField({\n text: 'AutoDownloadMedia',\n name: 'auto',\n checked: !rootScope.settings.autoDownloadNew.pFlags.disabled,\n listenerSetter: this.listenerSetter\n });\n\n const autoRow = new Row({\n checkboxField: autoCheckboxField,\n listenerSetter: this.listenerSetter\n });\n\n const onChange = () => {\n toggleDisability([resetButton],\n deepEqual(rootScope.settings.autoDownload, STATE_INIT.settings.autoDownload) &&\n deepEqual(rootScope.settings.autoDownloadNew, STATE_INIT.settings.autoDownloadNew));\n };\n\n const setSubtitles = () => {\n this.setAutoDownloadSubtitle(photoRow, rootScope.settings.autoDownload.photo /* state.settings.autoDownloadNew.photo_size_max */);\n this.setAutoDownloadSubtitle(videoRow, rootScope.settings.autoDownload.video/* , state.settings.autoDownloadNew.video_size_max */);\n this.setAutoDownloadSubtitle(fileRow, rootScope.settings.autoDownload.file, rootScope.settings.autoDownloadNew.file_size_max);\n };\n\n const openTab = (tabConstructor: SliderSuperTabEventableConstructable) => {\n const tab = this.slider.createTab(tabConstructor);\n tab.open();\n\n this.listenerSetter.add(tab.eventListener)('destroy', () => {\n setSubtitles();\n onChange();\n }, {once: true});\n };\n\n const photoRow = new Row({\n titleLangKey: 'AutoDownloadPhotos',\n subtitle: '',\n clickable: () => {\n openTab(AppAutoDownloadPhotoTab);\n },\n listenerSetter: this.listenerSetter\n });\n\n const videoRow = new Row({\n titleLangKey: 'AutoDownloadVideos',\n subtitle: '',\n clickable: () => {\n openTab(AppAutoDownloadVideoTab);\n },\n listenerSetter: this.listenerSetter\n });\n\n const fileRow = new Row({\n titleLangKey: 'AutoDownloadFiles',\n subtitle: '',\n clickable: () => {\n openTab(AppAutoDownloadFileTab);\n },\n listenerSetter: this.listenerSetter\n });\n\n const resetButton = Button('btn-primary btn-transparent primary', {icon: 'delete', text: 'ResetAutomaticMediaDownload'});\n attachClickEvent(resetButton, () => {\n confirmationPopup({\n titleLangKey: 'ResetAutomaticMediaDownloadAlertTitle',\n descriptionLangKey: 'ResetAutomaticMediaDownloadAlert',\n button: {\n langKey: 'Reset'\n }\n }).then(() => {\n const settings = rootScope.settings;\n settings.autoDownloadNew = copy(STATE_INIT.settings.autoDownloadNew);\n settings.autoDownload = copy(STATE_INIT.settings.autoDownload);\n rootScope.settings = settings;\n this.managers.appStateManager.setByKey('settings', settings);\n\n setSubtitles();\n autoCheckboxField.checked = !rootScope.settings.autoDownloadNew.pFlags.disabled;\n });\n });\n\n const onDisabledChange = () => {\n const disabled = !autoCheckboxField.checked;\n\n const autoDownloadNew = rootScope.settings.autoDownloadNew;\n if(disabled) {\n autoDownloadNew.pFlags.disabled = true;\n } else {\n delete autoDownloadNew.pFlags.disabled;\n }\n\n [photoRow, videoRow, fileRow].forEach((row) => {\n row.container.classList.toggle('is-disabled', disabled);\n });\n\n this.managers.appStateManager.setByKey('settings.autoDownloadNew', autoDownloadNew);\n\n onChange();\n };\n\n autoCheckboxField.input.addEventListener('change', onDisabledChange);\n onDisabledChange();\n setSubtitles();\n\n section.content.append(\n autoRow.container,\n photoRow.container,\n videoRow.container,\n fileRow.container,\n resetButton\n );\n\n this.scrollable.append(section.container);\n }\n }\n\n private setAutoDownloadSubtitle(row: Row, settings: AutoDownloadPeerTypeSettings, sizeMax?: number) {\n let key: LangPackKey;\n const args: FormatterArguments = [];\n\n const peerKeys = Object.keys(settings) as (keyof typeof AUTO_DOWNLOAD_FOR_KEYS)[];\n const enabledKeys = peerKeys.map((key) => settings[key] ? AUTO_DOWNLOAD_FOR_KEYS[key] : undefined).filter(Boolean);\n if(!enabledKeys.length || sizeMax === 0) {\n key = 'AutoDownloadOff';\n } else {\n const isAll = enabledKeys.length === peerKeys.length;\n if(sizeMax !== undefined) {\n key = isAll ? 'AutoDownloadUpToOnAllChats' : 'AutoDownloadOnUpToFor';\n args.push(formatBytes(sizeMax));\n } else {\n key = isAll ? 'AutoDownloadOnAllChats' : 'AutoDownloadOnFor';\n }\n\n if(!isAll) {\n const fragment = document.createElement('span');\n fragment.append(...join(enabledKeys.map((key) => i18n(key)), true, false));\n args.push(fragment);\n }\n }\n\n replaceContent(row.subtitle, i18n(key, args));\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AvailableReaction} from '../../../layer';\nimport RadioField from '../../radioField';\nimport Row, {RadioFormFromRows} from '../../row';\nimport SettingSection from '../../settingSection';\nimport SliderSuperTab from '../../sliderTab';\nimport wrapStickerToRow from '../../wrappers/stickerToRow';\n\nexport default class AppQuickReactionTab extends SliderSuperTab {\n public init() {\n this.setTitle('DoubleTapSetting');\n this.container.classList.add('quick-reaction-container');\n\n return Promise.all([\n this.managers.appReactionsManager.getQuickReaction(),\n this.managers.appReactionsManager.getAvailableReactions()\n ]).then(([quickReaction, availableReactions]) => {\n availableReactions = availableReactions.filter((reaction) => !reaction.pFlags.inactive);\n\n const section = new SettingSection();\n\n const name = 'quick-reaction';\n const rows = availableReactions.map((availableReaction) => {\n const radioField = new RadioField({\n name,\n text: availableReaction.title,\n value: availableReaction.reaction,\n alignRight: true\n });\n\n const row = new Row({\n radioField,\n havePadding: true\n });\n\n radioField.main.classList.add('quick-reaction-title');\n\n wrapStickerToRow({\n row,\n doc: availableReaction.static_icon,\n size: 'small'\n });\n\n if(availableReaction.reaction === (quickReaction as AvailableReaction).reaction) {\n radioField.setValueSilently(true);\n }\n\n return row;\n });\n\n const form = RadioFormFromRows(rows, (value) => {\n this.managers.appReactionsManager.setDefaultReaction({_: 'reactionEmoji', emoticon: value});\n });\n\n section.content.append(form);\n this.scrollable.append(section.container);\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport forEachReverse from '../../../helpers/array/forEachReverse';\nimport assumeType from '../../../helpers/assumeType';\nimport createContextMenu from '../../../helpers/dom/createContextMenu';\nimport positionElementByIndex from '../../../helpers/dom/positionElementByIndex';\nimport Sortable from '../../../helpers/dom/sortable';\nimport {StickerSet, MessagesAllStickers} from '../../../layer';\nimport {i18n, LangPackKey} from '../../../lib/langPack';\nimport wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';\nimport rootScope from '../../../lib/rootScope';\nimport CheckboxField from '../../checkboxField';\nimport LazyLoadQueue from '../../lazyLoadQueue';\nimport PopupElement from '../../popups';\nimport PopupStickers from '../../popups/stickers';\nimport Row, {CreateRowFromCheckboxField} from '../../row';\nimport SettingSection from '../../settingSection';\nimport SliderSuperTab from '../../sliderTab';\nimport wrapStickerSetThumb from '../../wrappers/stickerSetThumb';\nimport wrapStickerToRow from '../../wrappers/stickerToRow';\nimport AppQuickReactionTab from './quickReaction';\n\nexport default class AppStickersAndEmojiTab extends SliderSuperTab {\n public static getInitArgs() {\n return {\n allStickers: rootScope.managers.appStickersManager.getAllStickers(),\n quickReaction: rootScope.managers.appReactionsManager.getQuickReaction()\n };\n }\n\n public init(p: ReturnType<typeof AppStickersAndEmojiTab['getInitArgs']>) {\n this.container.classList.add('stickers-emoji-container');\n this.setTitle('StickersName');\n\n const promises: Promise<any>[] = [];\n\n {\n const section = new SettingSection({caption: 'LoopAnimatedStickersInfo'});\n\n const suggestStickersRow = new Row({\n icon: 'lamp',\n titleLangKey: 'Stickers.SuggestStickers',\n clickable: true,\n listenerSetter: this.listenerSetter,\n titleRightSecondary: true\n });\n\n const map: {[k in typeof rootScope.settings.stickers.suggest]: LangPackKey} = {\n all: 'SuggestStickersAll',\n installed: 'SuggestStickersInstalled',\n none: 'SuggestStickersNone'\n };\n\n const setStickersSuggestDescription = () => {\n suggestStickersRow.titleRight.replaceChildren(i18n(map[rootScope.settings.stickers.suggest]));\n };\n\n setStickersSuggestDescription();\n\n const setStickersSuggest = (value: typeof rootScope.settings.stickers.suggest) => {\n if(rootScope.settings.stickers.suggest === value) return;\n rootScope.settings.stickers.suggest = value;\n setStickersSuggestDescription();\n return this.managers.appStateManager.setByKey('settings.stickers.suggest', value);\n };\n\n createContextMenu({\n buttons: [{\n icon: 'stickers_face',\n text: 'SuggestStickersAll',\n onClick: setStickersSuggest.bind(this, 'all')\n }, {\n icon: 'newprivate',\n text: 'SuggestStickersInstalled',\n onClick: setStickersSuggest.bind(this, 'installed')\n }, {\n icon: 'stop',\n text: 'SuggestStickersNone',\n onClick: setStickersSuggest.bind(this, 'none')\n }],\n listenTo: suggestStickersRow.container,\n middleware: this.middlewareHelper.get(),\n listenForClick: true\n });\n\n const reactionsRow = new Row({\n titleLangKey: 'DoubleTapSetting',\n havePadding: true,\n clickable: () => {\n this.slider.createTab(AppQuickReactionTab).open();\n },\n listenerSetter: this.listenerSetter\n });\n\n const renderQuickReaction = () => {\n p.quickReaction.then((reaction) => {\n if(reaction._ === 'availableReaction') {\n return reaction.static_icon;\n } else {\n return this.managers.appEmojiManager.getCustomEmojiDocument(reaction.document_id);\n }\n }).then((doc) => {\n wrapStickerToRow({\n row: reactionsRow,\n doc,\n size: 'small'\n });\n });\n };\n\n renderQuickReaction();\n\n this.listenerSetter.add(rootScope)('quick_reaction', () => {\n p = AppStickersAndEmojiTab.getInitArgs();\n renderQuickReaction();\n });\n\n const loopStickersRow = new Row({\n icon: 'flip',\n titleLangKey: 'InstalledStickers.LoopAnimated',\n checkboxField: new CheckboxField({\n name: 'loop',\n stateKey: 'settings.stickers.loop',\n listenerSetter: this.listenerSetter,\n toggle: true\n }),\n listenerSetter: this.listenerSetter\n });\n\n section.content.append(\n reactionsRow.container,\n suggestStickersRow.container,\n loopStickersRow.container\n );\n\n this.scrollable.append(section.container);\n }\n\n {\n const section = new SettingSection({name: 'Emoji'});\n\n const suggestEmojiRow = new Row({\n icon: 'lamp',\n titleLangKey: 'GeneralSettings.EmojiPrediction',\n checkboxField: new CheckboxField({\n name: 'suggest-emoji',\n stateKey: 'settings.emoji.suggest',\n listenerSetter: this.listenerSetter,\n toggle: true\n }),\n listenerSetter: this.listenerSetter\n });\n const bigEmojiRow = new Row({\n icon: 'smile',\n titleLangKey: 'GeneralSettings.BigEmoji',\n checkboxField: new CheckboxField({\n name: 'emoji-big',\n stateKey: 'settings.emoji.big',\n listenerSetter: this.listenerSetter,\n toggle: true\n }),\n listenerSetter: this.listenerSetter\n });\n\n section.content.append(\n suggestEmojiRow.container,\n bigEmojiRow.container\n );\n\n this.scrollable.append(section.container);\n }\n\n {\n const section = new SettingSection({name: 'DynamicPackOrder', caption: 'DynamicPackOrderInfo'});\n\n const dynamicPackOrderRow = new Row({\n titleLangKey: 'DynamicPackOrder',\n checkboxField: new CheckboxField({\n name: 'dynamic-pack-order',\n stateKey: 'settings.stickers.dynamicPackOrder',\n listenerSetter: this.listenerSetter,\n toggle: true\n }),\n listenerSetter: this.listenerSetter\n });\n\n section.content.append(\n dynamicPackOrderRow.container\n );\n\n this.scrollable.append(section.container);\n }\n\n {\n const section = new SettingSection({name: 'Telegram.InstalledStickerPacksController', caption: 'StickersBotInfo'});\n\n const stickerSets: {[id: string]: Row} = {};\n\n const stickersContent = section.generateContentElement();\n\n const lazyLoadQueue = new LazyLoadQueue();\n const renderStickerSet = (stickerSet: StickerSet.stickerSet, method: 'append' | 'prepend' = 'append') => {\n const row = new Row({\n title: wrapEmojiText(stickerSet.title),\n subtitleLangKey: 'Stickers',\n subtitleLangArgs: [stickerSet.count],\n havePadding: true,\n clickable: () => {\n PopupElement.createPopup(PopupStickers, {id: stickerSet.id, access_hash: stickerSet.access_hash}).show();\n },\n listenerSetter: this.listenerSetter\n });\n\n row.container.dataset.id = '' + stickerSet.id;\n\n row.makeSortable();\n\n stickerSets[stickerSet.id] = row;\n\n const div = document.createElement('div');\n div.classList.add('row-media');\n\n wrapStickerSetThumb({\n set: stickerSet,\n container: div,\n group: 'GENERAL-SETTINGS',\n lazyLoadQueue,\n width: 36,\n height: 36,\n autoplay: true,\n middleware: this.middlewareHelper.get()\n });\n\n row.container.append(div);\n\n stickersContent[method](row.container);\n };\n\n const promise = p.allStickers.then((allStickers) => {\n assumeType<MessagesAllStickers.messagesAllStickers>(allStickers);\n const promises = allStickers.sets.map((stickerSet) => renderStickerSet(stickerSet));\n return Promise.all(promises);\n });\n\n promises.push(promise);\n\n this.listenerSetter.add(rootScope)('stickers_installed', (set) => {\n if(!stickerSets[set.id]) {\n renderStickerSet(set, 'prepend');\n }\n });\n\n this.listenerSetter.add(rootScope)('stickers_deleted', (set) => {\n if(stickerSets[set.id]) {\n stickerSets[set.id].container.remove();\n delete stickerSets[set.id];\n }\n });\n\n this.listenerSetter.add(rootScope)('stickers_order', ({type, order}) => {\n if(type !== 'stickers') {\n return;\n }\n\n order.forEach((id, idx) => {\n const row = stickerSets[id];\n if(!row) {\n return;\n }\n\n positionElementByIndex(row.container, stickersContent, idx)\n });\n });\n\n this.listenerSetter.add(rootScope)('stickers_top', (id) => {\n const row = stickerSets[id];\n if(!row) {\n return;\n }\n\n positionElementByIndex(row.container, stickersContent, 0);\n });\n\n new Sortable({\n list: stickersContent,\n middleware: this.middlewareHelper.get(),\n onSort: (idx, newIdx) => {\n const order = Array.from(stickersContent.children).map((el) => (el as HTMLElement).dataset.id);\n this.managers.appStickersManager.reorderStickerSets(order);\n }\n });\n\n this.scrollable.append(section.container);\n }\n\n return Promise.all(promises);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTab} from '../../slider';\nimport ButtonMenuToggle from '../../buttonMenuToggle';\nimport Button from '../../button';\nimport AppPrivacyAndSecurityTab from './privacyAndSecurity';\nimport AppGeneralSettingsTab from './generalSettings';\nimport AppEditProfileTab from './editProfile';\nimport AppChatFoldersTab from './chatFolders';\nimport AppNotificationsTab from './notifications';\nimport AppLanguageTab from './language';\nimport lottieLoader from '../../../lib/rlottie/lottieLoader';\nimport PopupPeer from '../../popups/peer';\nimport AppDataAndStorageTab from './dataAndStorage';\nimport ButtonIcon from '../../buttonIcon';\nimport PeerProfile from '../../peerProfile';\nimport rootScope from '../../../lib/rootScope';\nimport Row from '../../row';\nimport AppActiveSessionsTab from './activeSessions';\nimport {i18n, LangPackKey} from '../../../lib/langPack';\nimport {SliderSuperTabConstructable, SliderSuperTabEventable} from '../../sliderTab';\nimport PopupAvatar from '../../popups/avatar';\nimport {AccountAuthorizations, Authorization} from '../../../layer';\nimport PopupElement from '../../popups';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport SettingSection from '../../settingSection';\nimport AppStickersAndEmojiTab from './stickersAndEmoji';\nimport ButtonCorner from '../../buttonCorner';\n\nexport default class AppSettingsTab extends SliderSuperTab {\n private buttons: {\n edit: HTMLButtonElement,\n folders: HTMLButtonElement,\n general: HTMLButtonElement,\n notifications: HTMLButtonElement,\n storage: HTMLButtonElement,\n privacy: HTMLButtonElement,\n } = {} as any;\n private profile: PeerProfile;\n\n private languageRow: Row;\n private devicesRow: Row;\n\n private authorizations: Authorization.authorization[];\n private getAuthorizationsPromise: Promise<AccountAuthorizations.accountAuthorizations>;\n\n public async init() {\n this.container.classList.add('settings-container');\n this.setTitle('Settings');\n\n const btnMenu = ButtonMenuToggle({\n listenerSetter: this.listenerSetter,\n direction: 'bottom-left',\n buttons: [{\n icon: 'logout',\n text: 'EditAccount.Logout',\n onClick: () => {\n PopupElement.createPopup(PopupPeer, 'logout', {\n titleLangKey: 'LogOut',\n descriptionLangKey: 'LogOut.Description',\n buttons: [{\n langKey: 'LogOut',\n callback: () => {\n this.managers.apiManager.logOut();\n },\n isDanger: true\n }]\n }).show();\n }\n }]\n });\n\n this.buttons.edit = ButtonIcon('edit');\n\n this.header.append(this.buttons.edit, btnMenu);\n\n this.profile = new PeerProfile(this.managers, this.scrollable, this.listenerSetter, false);\n this.profile.init();\n this.profile.setPeer(rootScope.myId);\n const fillPromise = this.profile.fillProfileElements();\n\n const changeAvatarBtn = ButtonCorner({icon: 'cameraadd', className: 'profile-change-avatar'});\n attachClickEvent(changeAvatarBtn, () => {\n const canvas = document.createElement('canvas');\n PopupElement.createPopup(PopupAvatar).open(canvas, (upload) => {\n upload().then((inputFile) => {\n return this.managers.appProfileManager.uploadProfilePhoto(inputFile);\n });\n });\n }, {listenerSetter: this.listenerSetter});\n this.profile.element.lastElementChild.firstElementChild.append(changeAvatarBtn);\n\n const updateChangeAvatarBtn = async() => {\n const user = await this.managers.appUsersManager.getSelf();\n changeAvatarBtn.classList.toggle('hide', user.photo?._ !== 'userProfilePhoto');\n };\n\n updateChangeAvatarBtn();\n this.listenerSetter.add(rootScope)('avatar_update', ({peerId}) => {\n if(rootScope.myId === peerId) {\n updateChangeAvatarBtn();\n }\n });\n\n /* const div = document.createElement('div');\n //div.style.cssText = 'border-radius: 8px; overflow: hidden; width: 396px; height: 264px; flex: 0 0 auto; position: relative; margin: 10rem 0 10rem auto;';\n //div.style.width = '135px';\n //div.style.height = '100px';\n div.style.cssText = 'border-radius: 8px; overflow: hidden; width: 396px; height: 264px; flex: 0 0 auto; position: relative; margin: 10rem auto 10rem 0;';\n div.style.width = '135px';\n div.style.height = '100px';\n\n const img = document.createElement('img');\n img.src = 'assets/img/pepe.jpg';\n img.classList.add('media-photo');\n img.style.cssText = 'max-width: 100%;max-height: 100%;';\n\n div.append(img);\n\n div.addEventListener('click', () => {\n new AppMediaViewer().setSearchContext({peerId: 61004386, inputFilter: 'inputMessagesFilterPhotos'}).openMedia({\n _: 'message',\n mid: 1,\n peerId: 61004386,\n fromId: 61004386,\n message: '',\n media: {\n _: 'messageMediaPhoto',\n photo: {\n _: 'photo',\n url: img.src,\n downloaded: 111,\n sizes: [{\n _: 'photoSize',\n type: 'x',\n w: 618,\n h: 412\n }]\n }\n },\n date: Date.now() / 1000 | 0\n }, img);\n });\n\n this.scrollable.append(div); */\n\n const buttonsDiv = document.createElement('div');\n buttonsDiv.classList.add('profile-buttons');\n\n type ConstructorP<T> = T extends {\n new (...args: any[]): infer U;\n } ? U : never;\n\n const m = <T extends SliderSuperTabConstructable>(\n icon: string,\n text: LangPackKey,\n c: T,\n getInitArgs?: () => Promise<Parameters<ConstructorP<T>['init']>>\n ): {\n icon: string,\n text: LangPackKey,\n tabConstructor: T,\n getInitArgs?: typeof getInitArgs,\n // args?: ReturnType<typeof getInitArgs>\n args?: any\n } => {\n if(!getInitArgs) {\n const g = (c as any as typeof SliderSuperTab).getInitArgs;\n if(g) {\n // @ts-ignore\n getInitArgs = () => [g(this)];\n }\n }\n\n return {\n icon,\n text,\n tabConstructor: c,\n getInitArgs,\n args: getInitArgs?.()\n };\n };\n\n // const k = <T extends SliderSuperTabConstructable>(c: T): () => [ReturnType<ConstructorP<T>['getInitArgs']>] => {\n // return () => (c as any).getInitArgs(this);\n // };\n\n const b = [\n m('unmute', 'AccountSettings.Notifications', AppNotificationsTab),\n m('data', 'DataSettings', AppDataAndStorageTab),\n m('lock', 'AccountSettings.PrivacyAndSecurity', AppPrivacyAndSecurityTab),\n m('settings', 'Telegram.GeneralSettingsViewController', AppGeneralSettingsTab),\n m('folder', 'AccountSettings.Filters', AppChatFoldersTab),\n m('stickers_face', 'StickersName', AppStickersAndEmojiTab)\n ];\n\n const rows = b.map((item) => {\n const {icon, text: langPackKey, tabConstructor, getInitArgs} = item;\n return new Row({\n titleLangKey: langPackKey,\n icon,\n clickable: async() => {\n const args = item.args ? await item.args : [];\n const tab = this.slider.createTab(tabConstructor as any);\n tab.open(...args);\n\n if(tab instanceof SliderSuperTabEventable && getInitArgs) {\n tab.eventListener.addEventListener('destroyAfter', (promise) => {\n item.args = promise.then(() => getInitArgs() as any);\n });\n }\n },\n listenerSetter: this.listenerSetter\n });\n });\n\n const languageArgs = AppLanguageTab.getInitArgs();\n rows.push(\n this.devicesRow = new Row({\n titleLangKey: 'Devices',\n titleRightSecondary: ' ',\n icon: 'activesessions',\n clickable: async() => {\n if(!this.authorizations) {\n await this.updateActiveSessions();\n }\n\n const tab = this.slider.createTab(AppActiveSessionsTab);\n tab.authorizations = this.authorizations;\n tab.eventListener.addEventListener('destroy', () => {\n this.authorizations = undefined;\n this.updateActiveSessions(true);\n }, {once: true});\n tab.open();\n },\n listenerSetter: this.listenerSetter\n }),\n\n this.languageRow = new Row({\n titleLangKey: 'AccountSettings.Language',\n titleRightSecondary: i18n('LanguageName'),\n icon: 'language',\n clickable: () => {\n this.slider.createTab(AppLanguageTab).open(languageArgs);\n },\n listenerSetter: this.listenerSetter\n })\n );\n\n buttonsDiv.append(...rows.map((row) => row.container));\n\n // const profileSection = new SettingSection({fullWidth: true, noPaddingTop: true});\n // profileSection.content.append(this.profile.element);\n\n const buttonsSection = new SettingSection();\n buttonsSection.content.append(buttonsDiv);\n\n this.scrollable.append(this.profile.element/* profileSection.container */, buttonsSection.container);\n\n const getEditProfileArgs = () => {\n editProfileArgs = AppEditProfileTab.getInitArgs();\n };\n let editProfileArgs: ReturnType<typeof AppEditProfileTab['getInitArgs']>;\n attachClickEvent(this.buttons.edit, () => {\n const tab = this.slider.createTab(AppEditProfileTab);\n tab.open(editProfileArgs);\n }, {listenerSetter: this.listenerSetter});\n getEditProfileArgs();\n // this.listenerSetter.add(rootScope)('user_full_update', (userId) => {\n // if(rootScope.myId.toUserId() === userId) {\n // getEditProfileArgs();\n // }\n // });\n this.listenerSetter.add(rootScope)('user_update', (userId) => {\n if(rootScope.myId.toUserId() === userId) {\n getEditProfileArgs();\n }\n });\n\n lottieLoader.loadLottieWorkers();\n\n this.updateActiveSessions();\n\n (await fillPromise)();\n }\n\n private getAuthorizations(overwrite?: boolean) {\n if(this.getAuthorizationsPromise && !overwrite) return this.getAuthorizationsPromise;\n\n const promise = this.getAuthorizationsPromise = this.managers.apiManager.invokeApi('account.getAuthorizations')\n .finally(() => {\n if(this.getAuthorizationsPromise === promise) {\n this.getAuthorizationsPromise = undefined;\n }\n });\n\n return promise;\n }\n\n public updateActiveSessions(overwrite?: boolean) {\n return this.getAuthorizations(overwrite).then((auths) => {\n this.authorizations = auths.authorizations;\n this.devicesRow.titleRight.textContent = '' + this.authorizations.length;\n });\n }\n\n public onCloseAfterTimeout() {\n this.profile.destroy();\n return super.onCloseAfterTimeout();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport appSidebarLeft from '..';\nimport {InputFile} from '../../../layer';\nimport InputField from '../../inputField';\nimport {SliderSuperTab} from '../../slider';\nimport AvatarEdit from '../../avatarEdit';\nimport AppAddMembersTab from './addMembers';\nimport {_i18n} from '../../../lib/langPack';\nimport ButtonCorner from '../../buttonCorner';\nimport appImManager from '../../../lib/appManagers/appImManager';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport SettingSection from '../../settingSection';\n\nexport default class AppNewChannelTab extends SliderSuperTab {\n private uploadAvatar: () => Promise<InputFile> = null;\n\n private channelNameInputField: InputField;\n private channelDescriptionInputField: InputField;\n private nextBtn: HTMLButtonElement;\n private avatarEdit: AvatarEdit;\n\n public init() {\n this.container.classList.add('new-channel-container');\n this.setTitle('NewChannel');\n\n this.avatarEdit = new AvatarEdit((_upload) => {\n this.uploadAvatar = _upload;\n });\n\n const section = new SettingSection({\n caption: 'Channel.DescriptionHolderDescrpiton'\n });\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n this.channelNameInputField = new InputField({\n label: 'EnterChannelName',\n maxLength: 128\n });\n\n this.channelDescriptionInputField = new InputField({\n label: 'DescriptionOptionalPlaceholder',\n maxLength: 255\n });\n\n inputWrapper.append(this.channelNameInputField.container, this.channelDescriptionInputField.container);\n\n const onLengthChange = () => {\n this.nextBtn.classList.toggle('is-visible', !!this.channelNameInputField.value.length &&\n !this.channelNameInputField.input.classList.contains('error') &&\n !this.channelDescriptionInputField.input.classList.contains('error'));\n };\n\n this.channelNameInputField.input.addEventListener('input', onLengthChange);\n this.channelDescriptionInputField.input.addEventListener('input', onLengthChange);\n\n this.nextBtn = ButtonCorner({icon: 'arrow_next'});\n\n attachClickEvent(this.nextBtn, () => {\n const title = this.channelNameInputField.value;\n const about = this.channelDescriptionInputField.value;\n\n this.nextBtn.disabled = true;\n this.managers.appChatsManager.createChannel({\n title,\n about,\n broadcast: true\n }).then((channelId) => {\n if(this.uploadAvatar) {\n this.uploadAvatar().then((inputFile) => {\n this.managers.appChatsManager.editPhoto(channelId, inputFile);\n });\n }\n\n appImManager.setInnerPeer({peerId: channelId.toPeerId(true)});\n\n appSidebarLeft.removeTabFromHistory(this);\n this.slider.createTab(AppAddMembersTab).open({\n type: 'channel',\n skippable: true,\n title: 'GroupAddMembers',\n placeholder: 'SendMessageTo',\n takeOut: (peerIds) => {\n return this.managers.appChatsManager.inviteToChannel(channelId, peerIds);\n }\n });\n });\n }, {listenerSetter: this.listenerSetter});\n\n this.content.append(this.nextBtn);\n section.content.append(this.avatarEdit.container, inputWrapper);\n this.scrollable.append(section.container);\n }\n\n public onCloseAfterTimeout() {\n this.avatarEdit.clear();\n this.uploadAvatar = null;\n this.channelNameInputField.value = '';\n this.channelDescriptionInputField.value = '';\n this.nextBtn.disabled = false;\n return super.onCloseAfterTimeout();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport InputField from '../inputField';\nimport PopupElement from '.';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport EditPeer from '../editPeer';\nimport {_i18n} from '../../lib/langPack';\nimport TelInputField from '../telInputField';\nimport {formatPhoneNumber} from '../../helpers/formatPhoneNumber';\nimport {toastNew} from '../toast';\n\nexport default class PopupCreateContact extends PopupElement {\n constructor() {\n super('popup-create-contact popup-send-photo popup-new-media', {closable: true, withConfirm: 'Add', title: 'AddContactTitle'});\n this.construct();\n }\n\n private async construct() {\n attachClickEvent(this.btnConfirm, () => {\n const promise = this.managers.appUsersManager.importContact(nameInputField.value, lastNameInputField.value, telInputField.value);\n\n promise.then(() => {\n this.hide();\n }, (err) => {\n if(err.type === 'NO_USER') {\n toastNew({langPackKey: 'Contacts.PhoneNumber.NotRegistred'});\n editPeer.disabled = false;\n }\n });\n\n editPeer.lockWithPromise(promise);\n }, {listenerSetter: this.listenerSetter});\n\n const inputFields: InputField[] = [];\n const div = document.createElement('div');\n div.classList.add('name-fields');\n const nameInputField = new InputField({\n label: 'FirstName',\n name: 'create-contact-name',\n maxLength: 70,\n required: true\n });\n const lastNameInputField = new InputField({\n label: 'LastName',\n name: 'create-contact-lastname',\n maxLength: 70\n });\n const telInputField = new TelInputField({required: true});\n inputFields.push(nameInputField, lastNameInputField, telInputField);\n\n const onInput = () => {\n const name = nameInputField.value + ' ' + lastNameInputField.value;\n // const abbr = getAbbreviation(name);\n editPeer.avatarElem.peerTitle = name;\n editPeer.avatarElem.update();\n };\n\n this.listenerSetter.add(nameInputField.input)('input', onInput);\n this.listenerSetter.add(lastNameInputField.input)('input', onInput);\n\n telInputField.validate = () => {\n return !!telInputField.value.match(/\\d/);\n };\n\n const user = await this.managers.appUsersManager.getSelf();\n const formatted = formatPhoneNumber(user.phone);\n if(formatted.code) {\n telInputField.value = '+' + formatted.code.country_code;\n }\n\n const editPeer = new EditPeer({\n inputFields,\n listenerSetter: this.listenerSetter,\n doNotEditAvatar: true,\n nextBtn: this.btnConfirm,\n avatarSize: 100\n });\n\n div.append(nameInputField.container, lastNameInputField.container, editPeer.avatarElem);\n this.container.append(div, telInputField.container);\n\n this.show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTab} from '../../slider';\nimport appDialogsManager from '../../../lib/appManagers/appDialogsManager';\nimport InputSearch from '../../inputSearch';\nimport {IS_MOBILE} from '../../../environment/userAgent';\nimport {canFocus} from '../../../helpers/dom/canFocus';\nimport windowSize from '../../../helpers/windowSize';\nimport ButtonCorner from '../../buttonCorner';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport PopupCreateContact from '../../popups/createContact';\nimport SortedUserList from '../../sortedUserList';\nimport {getMiddleware} from '../../../helpers/middleware';\nimport replaceContent from '../../../helpers/dom/replaceContent';\nimport rootScope from '../../../lib/rootScope';\nimport PopupElement from '../../popups';\n\n// TODO: поиск по людям глобальный, если не нашло в контактах никого\n\nexport default class AppContactsTab extends SliderSuperTab {\n private inputSearch: InputSearch;\n private middleware: ReturnType<typeof getMiddleware>;\n private sortedUserList: SortedUserList;\n\n public init() {\n this.container.id = 'contacts-container';\n\n // this.list = appDialogsManager.createChatList(/* {avatarSize: 48, handheldsSize: 66} */);\n\n const btnAdd = ButtonCorner({icon: 'add', className: 'is-visible'});\n this.content.append(btnAdd);\n\n attachClickEvent(btnAdd, () => {\n PopupElement.createPopup(PopupCreateContact);\n }, {listenerSetter: this.listenerSetter});\n\n this.inputSearch = new InputSearch('Search', (value) => {\n this.openContacts(value);\n });\n\n this.listenerSetter.add(rootScope)('contacts_update', async(userId) => {\n const isContact = await this.managers.appUsersManager.isContact(userId);\n const peerId = userId.toPeerId();\n if(isContact) this.sortedUserList.add(peerId);\n else this.sortedUserList.delete(peerId);\n });\n\n this.title.replaceWith(this.inputSearch.container);\n\n this.middleware = getMiddleware();\n\n this.openContacts();\n\n // preload contacts\n // appUsersManager.getContacts();\n }\n\n protected createList() {\n const sortedUserList = new SortedUserList({\n managers: this.managers\n });\n const list = sortedUserList.list;\n list.id = 'contacts';\n list.classList.add('contacts-container');\n appDialogsManager.setListClickListener(list, () => {\n this.close();\n }, undefined, true);\n return sortedUserList;\n }\n\n protected onClose() {\n this.middleware.clean();\n /* // need to clear, and left 1 page for smooth slide\n let pageCount = appPhotosManager.windowH / 56 * 1.25 | 0;\n (Array.from(this.list.children) as HTMLElement[]).slice(pageCount).forEach((el) => el.remove()); */\n }\n\n protected onOpenAfterTimeout() {\n if(IS_MOBILE || !canFocus(true)) return;\n this.inputSearch.input.focus();\n }\n\n public openContacts(query?: string) {\n this.middleware.clean();\n const middleware = this.middleware.get();\n this.scrollable.onScrolledBottom = null;\n this.scrollable.container.textContent = '';\n\n this.managers.appUsersManager.getContactsPeerIds(query, undefined, 'online').then((contacts) => {\n if(!middleware()) {\n return;\n }\n\n const sortedUserList = this.sortedUserList = this.createList();\n\n let renderPage = () => {\n const pageCount = windowSize.height / 56 * 1.25 | 0;\n const arr = contacts.splice(0, pageCount); // надо splice!\n\n arr.forEach((peerId) => {\n sortedUserList.add(peerId);\n });\n\n if(!contacts.length) {\n renderPage = undefined;\n this.scrollable.onScrolledBottom = null;\n }\n };\n\n renderPage();\n this.scrollable.onScrolledBottom = () => {\n if(renderPage) {\n renderPage();\n } else {\n this.scrollable.onScrolledBottom = null;\n }\n };\n\n replaceContent(this.scrollable.container, sortedUserList.list);\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport appDialogsManager from '../../../lib/appManagers/appDialogsManager';\nimport {SliderSuperTab} from '../../slider';\nimport {FOLDER_ID_ARCHIVE, REAL_FOLDER_ID} from '../../../lib/mtproto/mtproto_config';\n\nexport default class AppArchivedTab extends SliderSuperTab {\n private static filterId: REAL_FOLDER_ID = FOLDER_ID_ARCHIVE;\n private wasFilterId: number;\n\n public init() {\n this.wasFilterId = appDialogsManager.filterId;\n\n this.container.id = 'chats-archived-container';\n this.setTitle('ArchivedChats');\n\n this.header.classList.add('can-have-forum');\n this.content.classList.add('can-have-forum');\n\n if(!appDialogsManager.xds[AppArchivedTab.filterId]) {\n const {ul, scrollable} = appDialogsManager.l({\n title: undefined,\n id: AppArchivedTab.filterId,\n localId: FOLDER_ID_ARCHIVE\n });\n scrollable.container.append(ul);\n }\n\n const scrollable = appDialogsManager.xds[AppArchivedTab.filterId].scrollable;\n this.scrollable.container.replaceWith(scrollable.container);\n scrollable.attachBorderListeners(this.container);\n // ! DO NOT UNCOMMENT NEXT LINE - chats will stop loading on scroll after closing the tab\n // this.scrollable = scrollable;\n return appDialogsManager.setFilterIdAndChangeTab(AppArchivedTab.filterId).then(({cached, renderPromise}) => {\n if(cached) {\n return renderPromise;\n }\n });\n }\n\n // вообще, так делать нельзя, но нет времени чтобы переделать главный чатлист на слайд...\n onOpenAfterTimeout() {\n appDialogsManager.xds[this.wasFilterId].clear();\n }\n\n onClose() {\n this.scrollable.onAdditionalScroll = undefined;\n appDialogsManager.setFilterIdAndChangeTab(this.wasFilterId);\n }\n\n onCloseAfterTimeout() {\n appDialogsManager.xds[AppArchivedTab.filterId].clear();\n return super.onCloseAfterTimeout();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTab} from '../../slider';\nimport ButtonCorner from '../../buttonCorner';\nimport AppNewGroupTab from './newGroup';\nimport {toast} from '../../toast';\nimport {ButtonMenuItemOptions} from '../../buttonMenu';\nimport {i18n, join, _i18n} from '../../../lib/langPack';\nimport rootScope from '../../../lib/rootScope';\nimport wrapSticker from '../../wrappers/sticker';\nimport SortedUserList from '../../sortedUserList';\nimport {PeerLocated, Update, Updates} from '../../../layer';\nimport {SettingChatListSection} from '..';\nimport appDialogsManager from '../../../lib/appManagers/appDialogsManager';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport confirmationPopup from '../../confirmationPopup';\nimport getPeerId from '../../../lib/appManagers/utils/peers/getPeerId';\nimport type LazyLoadQueue from '../../lazyLoadQueue';\n\nexport default class AppPeopleNearbyTab extends SliderSuperTab {\n private latestLocationSaved: {latitude: number, longitude: number, accuracy: number};\n private isLocationWatched: boolean = false;\n private errorCategory: HTMLElement;\n private retryBtn: HTMLButtonElement;\n private btnOptions: HTMLButtonElement;\n private menuButtons: (ButtonMenuItemOptions & {verify?: () => boolean})[];\n\n protected lazyLoadQueue: LazyLoadQueue;\n protected peopleSection: SettingChatListSection;\n protected chatsSection: SettingChatListSection;\n\n protected locatedPeers: Map<PeerId, PeerLocated.peerLocated>;\n\n // public async init() {\n // this.container.classList.add('people-nearby-container');\n // this.setTitle('PeopleNearby');\n\n // this.errorCategory = document.createElement('div');\n // this.errorCategory.classList.add('text', 'hide', 'nearby-error');\n\n // this.retryBtn = ButtonCorner({icon: 'check'});\n\n // const emoji = '🧭';\n // const doc = await this.managers.appStickersManager.getAnimatedEmojiSticker(emoji);\n // const stickerContainer = document.createElement('div');\n // stickerContainer.classList.add('sticker-container');\n\n // if(doc) {\n // wrapSticker({\n // doc,\n // div: stickerContainer,\n // loop: false,\n // play: true,\n // width: 86,\n // height: 86,\n // emoji,\n // needUpscale: true\n // }).then(() => {\n // // this.animation = player;\n // });\n // } else {\n // stickerContainer.classList.add('media-sticker-wrapper');\n // }\n\n // const caption = document.createElement('div');\n // caption.classList.add('caption');\n // _i18n(caption, 'PeopleNearbyInfo2');\n\n // this.locatedPeers = new Map();\n\n // const m = () => {\n // const sortedUserList = new SortedUserList({\n // avatarSize: 42,\n // createChatListOptions: {\n // dialogSize: 48,\n // new: true\n // },\n // autonomous: false,\n // onUpdate: (element) => {\n // const peer = this.locatedPeers.get(element.id);\n // const elements: HTMLElement[] = [\n // this.parseDistance(peer.distance)\n // ];\n\n // if(!element.id.isUser()) {\n // elements.push(this.managers.appProfileManager.getChatMembersString(element.id.toChatId()));\n // }\n\n // element.dom.lastMessageSpan.textContent = '';\n // element.dom.lastMessageSpan.append(...join(elements, false));\n // },\n // getIndex: (element) => {\n // const peer = this.locatedPeers.get(element.id);\n // return 0x7FFFFFFF - peer.distance;\n // },\n // appUsersManager: this.managers.appUsersManager\n // });\n\n // appDialogsManager.setListClickListener(sortedUserList.list, undefined, undefined, false);\n\n // return sortedUserList;\n // };\n\n // const peopleSection = this.peopleSection = new SettingChatListSection({\n // name: 'PeopleNearbyHeader',\n // sortedList: m()\n // });\n\n // const chatsSection = this.chatsSection = new SettingChatListSection({\n // name: 'ChatsNearbyHeader',\n // sortedList: m()\n // });\n\n // const btnMakeVisible = peopleSection.makeButton({\n // text: 'MakeMyselfVisible',\n // icon: 'location'\n // });\n\n // const btnMakeInvisible = peopleSection.makeButton({\n // text: 'StopShowingMe',\n // icon: 'location'\n // });\n\n // const btnCreateGroup = chatsSection.makeButton({\n // text: 'NearbyCreateGroup',\n // icon: 'newgroup'\n // });\n\n // attachClickEvent(btnMakeVisible, () => {\n // confirmationPopup({\n // titleLangKey: 'MakeMyselfVisibleTitle',\n // descriptionLangKey: 'MakeMyselfVisibleInfo',\n // button: {\n // langKey: 'OK'\n // }\n // }).then(() => {\n // this.startWatching();\n // });\n // }, {listenerSetter: this.listenerSetter});\n\n // attachClickEvent(btnMakeInvisible, () => {\n // this.stopWatching();\n // }, {listenerSetter: this.listenerSetter});\n\n // attachClickEvent(btnCreateGroup, () => {\n // this.slider.createTab(AppNewGroupTab).open([], true);\n // }, {listenerSetter: this.listenerSetter});\n\n // btnMakeVisible.classList.add('primary');\n // btnMakeInvisible.classList.add('danger');\n // btnCreateGroup.classList.add('primary');\n\n // this.content.append(this.retryBtn);\n // this.scrollable.append(\n // stickerContainer,\n // caption,\n // peopleSection.container,\n // chatsSection.container,\n // this.errorCategory\n // );\n // }\n\n private parseDistance(distance: number) {\n if(rootScope.settings.distanceUnit === 'miles') {\n if(distance > 1609.34) {\n return i18n('MilesAway', [Math.round(distance / 1609)]);\n } else {\n return i18n('FootsAway', [Math.round(distance * 3.281)]);\n }\n } else {\n if(distance >= 1000) {\n return i18n('KMetersAway2', [distance / 1000]);\n } else {\n return i18n('MetersAway2', [distance]);\n }\n }\n }\n\n // public open() {\n // const result = super.open();\n // result.then(() => {\n // this.retryBtn.classList.remove('is-visible');\n // navigator.geolocation.getCurrentPosition((location) => {\n // this.latestLocationSaved = {\n // latitude: location.coords.latitude,\n // longitude: location.coords.longitude,\n // accuracy: location.coords.accuracy\n // };\n\n // console.log(this.latestLocationSaved);\n\n // this.managers.appUsersManager.getLocated(\n // location.coords.latitude,\n // location.coords.longitude,\n // location.coords.accuracy\n // ).then((response) => {\n // const update = (response as Updates.updates).updates[0] as Update.updatePeerLocated;\n // const peers = update.peers as PeerLocated.peerLocated[];\n // const orderedPeers = peers.sort((a, b) => a.distance - b.distance);\n // const groupsCounter = peers.filter((e) => e.peer._ == 'peerChannel').length;\n // const usersCounter = peers.filter((e) => e.peer._ != 'peerChannel').length;\n // orderedPeers?.forEach((peer) => {\n // const peerId = getPeerId(peer.peer);\n // const section = peerId.isUser() ? this.peopleSection : this.chatsSection;\n // this.locatedPeers.set(peerId, peer);\n // section.sortedList.add(peerId);\n // });\n\n // this.errorCategory.classList.toggle('hide', !!(usersCounter || groupsCounter));\n // this.errorCategory.innerHTML = 'No groups or channels found around you.';\n // });\n // }, (error) => {\n // this.errorCategory.classList.remove('hide');\n // this.retryBtn.classList.add('is-visible');\n // this.retryBtn.addEventListener('click', this.open);\n // if(error instanceof GeolocationPositionError) {\n // this.errorCategory.innerHTML = 'Location permission denied. Click below to retry.';\n // } else {\n // this.errorCategory.innerHTML = 'An error has occurred. Please retry later clicking the button below.';\n // }\n // });\n // });\n\n // return result;\n // }\n\n private startWatching() {\n if(!this.latestLocationSaved || this.isLocationWatched) return;\n this.isLocationWatched = true;\n\n toast('Your position is now being shared. Do not close the page or it will be suspended.');\n\n this.managers.appUsersManager.getLocated(\n this.latestLocationSaved.latitude,\n this.latestLocationSaved.longitude,\n this.latestLocationSaved.accuracy,\n true, // background parameter\n 0x7fffffff // self_expires parameter\n );\n\n navigator.geolocation.watchPosition((result) => {\n const isLongitudeDifferent = result.coords.longitude !== this.latestLocationSaved.longitude;\n const isLatitudeDifferent = result.coords.latitude !== this.latestLocationSaved.latitude;\n const distanceCheck = this.calculateDistance(\n result.coords.latitude, result.coords.longitude,\n this.latestLocationSaved.latitude, this.latestLocationSaved.longitude\n ) > 100;\n\n if((isLatitudeDifferent || isLongitudeDifferent) && distanceCheck) {\n this.managers.appUsersManager.getLocated(\n result.coords.latitude,\n result.coords.longitude,\n result.coords.accuracy,\n true, // background parameter\n 0x7fffffff // self_expires parameter\n );\n this.latestLocationSaved = {\n latitude: result.coords.latitude,\n longitude: result.coords.longitude,\n accuracy: result.coords.accuracy\n }\n }\n });\n }\n\n private stopWatching() {\n if(!this.isLocationWatched) return;\n this.isLocationWatched = false;\n toast('The sharing of your position has been stopped. You will no longer be visible to other users.');\n this.managers.appUsersManager.getLocated(\n 0, // latitude parameter\n 0, // longitude parameter\n 0, // accuracy parameter\n false, // background parameter\n 0 // self_expires parameter\n );\n }\n\n private calculateDistance(lat1: number, long1: number, lat2: number, long2: number) {\n const p = 0.017453292519943295; // Math.PI/180\n return (\n 12742 * Math.asin(\n Math.sqrt(\n (0.5 - Math.cos((lat2 - lat1) * p)) +\n (\n Math.cos(lat1 * p) * Math.cos(lat2 * p) *\n (1 - Math.cos((long2 - long1) * p)/2)\n )\n )\n )\n );\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport appImManager from '../../lib/appManagers/appImManager';\nimport rootScope from '../../lib/rootScope';\nimport {SearchGroup} from '../appSearch';\nimport '../avatar';\nimport Scrollable, {ScrollableX} from '../scrollable';\nimport InputSearch from '../inputSearch';\nimport SidebarSlider from '../slider';\nimport TransitionSlider from '../transition';\nimport AppNewGroupTab from './tabs/newGroup';\nimport AppSearchSuper from '../appSearchSuper.';\nimport {DateData, fillTipDates} from '../../helpers/date';\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport AppSettingsTab from './tabs/settings';\nimport AppNewChannelTab from './tabs/newChannel';\nimport AppContactsTab from './tabs/contacts';\nimport AppArchivedTab from './tabs/archivedTab';\nimport AppAddMembersTab from './tabs/addMembers';\nimport I18n, {FormatterArguments, i18n, i18n_, LangPackKey} from '../../lib/langPack';\nimport AppPeopleNearbyTab from './tabs/peopleNearby';\nimport {ButtonMenuItemOptions} from '../buttonMenu';\nimport CheckboxField from '../checkboxField';\nimport {IS_MOBILE_SAFARI} from '../../environment/userAgent';\nimport appNavigationController, {NavigationItem} from '../appNavigationController';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport findUpTag from '../../helpers/dom/findUpTag';\nimport PeerTitle from '../peerTitle';\nimport App from '../../config/app';\nimport ButtonMenuToggle from '../buttonMenuToggle';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport sessionStorage from '../../lib/sessionStorage';\nimport {attachClickEvent, CLICK_EVENT_NAME, simulateClickEvent} from '../../helpers/dom/clickEvent';\nimport ButtonIcon from '../buttonIcon';\nimport confirmationPopup from '../confirmationPopup';\nimport IS_GEOLOCATION_SUPPORTED from '../../environment/geolocationSupport';\nimport type SortedUserList from '../sortedUserList';\nimport Button, {ButtonOptions} from '../button';\nimport noop from '../../helpers/noop';\nimport ripple from '../ripple';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport formatNumber from '../../helpers/number/formatNumber';\nimport AvatarElement from '../avatar';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport themeController from '../../helpers/themeController';\nimport contextMenuController from '../../helpers/contextMenuController';\nimport {DIALOG_LIST_ELEMENT_TAG} from '../../lib/appManagers/appDialogsManager';\nimport apiManagerProxy from '../../lib/mtproto/mtprotoworker';\nimport SettingSection, {SettingSectionOptions} from '../settingSection';\nimport {FOLDER_ID_ARCHIVE} from '../../lib/mtproto/mtproto_config';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport {fastRaf} from '../../helpers/schedulers';\nimport {getInstallPrompt} from '../../helpers/dom/installPrompt';\nimport liteMode from '../../helpers/liteMode';\nimport AppPowerSavingTab from './tabs/powerSaving';\n\nexport const LEFT_COLUMN_ACTIVE_CLASSNAME = 'is-left-column-shown';\n\nexport class AppSidebarLeft extends SidebarSlider {\n private toolsBtn: HTMLElement;\n private backBtn: HTMLButtonElement;\n // private searchInput = document.getElementById('global-search') as HTMLInputElement;\n private inputSearch: InputSearch;\n\n public archivedCount: HTMLSpanElement;\n public rect: DOMRect;\n\n private newBtnMenu: HTMLElement;\n\n // private log = logger('SL');\n\n private searchGroups: {[k in 'contacts' | 'globalContacts' | 'messages' | 'people' | 'recent']: SearchGroup} = {} as any;\n private searchSuper: AppSearchSuper;\n\n private updateBtn: HTMLElement;\n private hasUpdate: boolean;\n\n constructor() {\n super({\n sidebarEl: document.getElementById('column-left') as HTMLDivElement,\n navigationType: 'left'\n });\n }\n\n construct(managers: AppManagers) {\n this.managers = managers;\n // this._selectTab(0); // make first tab as default\n\n this.inputSearch = new InputSearch('Search');\n const sidebarHeader = this.sidebarEl.querySelector('.item-main .sidebar-header');\n sidebarHeader.append(this.inputSearch.container);\n\n const onNewGroupClick = () => {\n this.createTab(AppAddMembersTab).open({\n type: 'chat',\n skippable: true,\n takeOut: (peerIds) => this.createTab(AppNewGroupTab).open(peerIds),\n title: 'GroupAddMembers',\n placeholder: 'SendMessageTo'\n });\n };\n\n const onContactsClick = () => {\n this.createTab(AppContactsTab).open();\n };\n\n // this.toolsBtn = this.sidebarEl.querySelector('.sidebar-tools-button') as HTMLButtonElement;\n this.backBtn = this.sidebarEl.querySelector('.sidebar-back-button') as HTMLButtonElement;\n\n const btnArchive: typeof menuButtons[0] = {\n icon: 'archive',\n text: 'ArchivedChats',\n onClick: () => {\n this.createTab(AppArchivedTab).open();\n },\n verify: async() => {\n const folder = await this.managers.dialogsStorage.getFolderDialogs(FOLDER_ID_ARCHIVE, false);\n return !!folder.length || !(await this.managers.dialogsStorage.isDialogsLoaded(FOLDER_ID_ARCHIVE));\n }\n };\n\n const themeCheckboxField = new CheckboxField({\n toggle: true,\n checked: themeController.getTheme().name === 'night'\n });\n themeCheckboxField.input.addEventListener('change', async() => {\n themeController.switchTheme(themeCheckboxField.input.checked ? 'night' : 'day');\n });\n\n rootScope.addEventListener('theme_change', () => {\n themeCheckboxField.setValueSilently(themeController.getTheme().name === 'night');\n });\n\n const menuButtons: (ButtonMenuItemOptions & {verify?: () => boolean | Promise<boolean>})[] = [{\n icon: 'savedmessages',\n text: 'SavedMessages',\n onClick: () => {\n setTimeout(() => { // menu doesn't close if no timeout (lol)\n appImManager.setPeer({\n peerId: appImManager.myId\n });\n }, 0);\n }\n }, btnArchive, {\n icon: 'user',\n text: 'Contacts',\n onClick: onContactsClick\n }, IS_GEOLOCATION_SUPPORTED ? {\n icon: 'group',\n text: 'PeopleNearby',\n onClick: () => {\n this.createTab(AppPeopleNearbyTab).open();\n }\n } : undefined, {\n icon: 'settings',\n text: 'Settings',\n onClick: () => {\n this.createTab(AppSettingsTab).open();\n }\n }, {\n icon: 'darkmode',\n text: 'DarkMode',\n onClick: () => {\n\n },\n checkboxField: themeCheckboxField\n }, {\n icon: 'animations',\n text: 'Animations',\n onClick: () => {\n\n },\n checkboxField: new CheckboxField({\n toggle: true,\n checked: true,\n stateKey: 'settings.liteMode.animations',\n stateValueReverse: true\n }),\n verify: () => !liteMode.isEnabled()\n }, {\n icon: 'animations',\n text: 'LiteMode.Title',\n onClick: () => {\n this.createTab(AppPowerSavingTab).open();\n },\n verify: () => liteMode.isEnabled()\n }, {\n icon: 'help',\n text: 'TelegramFeatures',\n onClick: () => {\n const url = I18n.format('TelegramFeaturesUrl', true);\n appImManager.openUrl(url);\n }\n }, {\n icon: 'bug',\n text: 'ReportBug',\n onClick: () => {\n const a = document.createElement('a');\n a.target = '_blank';\n a.href = 'https://bugs.telegram.org/?tag_ids=40&sort=time';\n document.body.append(a);\n a.click();\n setTimeout(() => {\n a.remove();\n }, 0);\n }\n }, {\n icon: 'char z',\n text: 'ChatList.Menu.SwitchTo.Z',\n onClick: () => {\n Promise.all([\n sessionStorage.set({kz_version: 'Z'}),\n sessionStorage.delete('tgme_sync')\n ]).then(() => {\n location.href = 'https://web.telegram.org/z/';\n });\n },\n verify: () => App.isMainDomain\n }, /* {\n icon: 'char w',\n text: 'ChatList.Menu.SwitchTo.Webogram',\n onClick: () => {\n sessionStorage.delete('tgme_sync').then(() => {\n location.href = 'https://web.telegram.org/?legacy=1';\n });\n },\n verify: () => App.isMainDomain\n }, */ {\n icon: 'download',\n text: 'PWA.Install',\n onClick: () => {\n const installPrompt = getInstallPrompt();\n installPrompt?.();\n },\n verify: () => !!getInstallPrompt()\n }];\n\n const filteredButtons = menuButtons.filter(Boolean);\n\n this.toolsBtn = ButtonMenuToggle({\n direction: 'bottom-right',\n buttons: filteredButtons,\n onOpen: (e, btnMenu) => {\n const btnMenuFooter = document.createElement('a');\n btnMenuFooter.href = 'https://github.com/morethanwords/tweb/blob/master/CHANGELOG.md';\n btnMenuFooter.target = '_blank';\n btnMenuFooter.rel = 'noopener noreferrer';\n btnMenuFooter.classList.add('btn-menu-footer');\n btnMenuFooter.addEventListener(CLICK_EVENT_NAME, (e) => {\n e.stopPropagation();\n contextMenuController.close();\n });\n const t = document.createElement('span');\n t.classList.add('btn-menu-footer-text');\n t.textContent = 'Telegram Web' + App.suffix + ' '/* ' alpha ' */ + App.versionFull;\n btnMenuFooter.append(t);\n btnMenu.classList.add('has-footer');\n btnMenu.append(btnMenuFooter);\n\n btnArchive.element?.append(this.archivedCount);\n }\n });\n this.toolsBtn.classList.remove('tgico-more');\n this.toolsBtn.classList.add('sidebar-tools-button', 'is-visible');\n\n this.backBtn.parentElement.insertBefore(this.toolsBtn, this.backBtn);\n\n this.newBtnMenu = ButtonMenuToggle({\n direction: 'top-left',\n buttons: [{\n icon: 'newchannel',\n text: 'NewChannel',\n onClick: () => {\n this.createTab(AppNewChannelTab).open();\n }\n }, {\n icon: 'newgroup',\n text: 'NewGroup',\n onClick: onNewGroupClick\n }, {\n icon: 'newprivate',\n text: 'NewPrivateChat',\n onClick: onContactsClick\n }]\n });\n this.newBtnMenu.className = 'btn-circle rp btn-corner z-depth-1 btn-menu-toggle animated-button-icon';\n this.newBtnMenu.tabIndex = -1;\n this.newBtnMenu.insertAdjacentHTML('afterbegin', `\n <span class=\"tgico tgico-newchat_filled\"></span>\n <span class=\"tgico tgico-close\"></span>\n `);\n this.newBtnMenu.id = 'new-menu';\n sidebarHeader.nextElementSibling.append(this.newBtnMenu);\n\n this.updateBtn = document.createElement('div');\n this.updateBtn.className = 'btn-circle rp btn-corner z-depth-1 btn-update is-hidden';\n this.updateBtn.tabIndex = -1;\n ripple(this.updateBtn);\n this.updateBtn.append(i18n('Update'));\n\n attachClickEvent(this.updateBtn, () => {\n if(this.updateBtn.classList.contains('is-hidden')) {\n return;\n }\n\n location.reload();\n });\n\n sidebarHeader.nextElementSibling.append(this.updateBtn);\n\n this.inputSearch.input.addEventListener('focus', () => this.initSearch(), {once: true});\n\n this.archivedCount = document.createElement('span');\n this.archivedCount.className = 'archived-count badge badge-24 badge-gray';\n\n rootScope.addEventListener('folder_unread', (folder) => {\n if(folder.id === FOLDER_ID_ARCHIVE) {\n // const count = folder.unreadMessagesCount;\n const count = folder.unreadPeerIds.size;\n this.archivedCount.textContent = '' + formatNumber(count, 1);\n this.archivedCount.classList.toggle('hide', !count);\n }\n });\n\n this.managers.appUsersManager.getTopPeers('correspondents');\n\n // Focus search input by pressing Escape\n const navigationItem: NavigationItem = {\n type: 'global-search-focus',\n onPop: () => {\n setTimeout(() => {\n this.inputSearch.input.focus();\n }, 0);\n\n return false;\n },\n noHistory: true\n };\n appNavigationController.pushItem(navigationItem);\n\n apiManagerProxy.getState().then(() => {\n const CHECK_UPDATE_INTERVAL = 1800e3;\n const checkUpdateInterval = setInterval(() => {\n fetch('version', {cache: 'no-cache'})\n .then((res) => (res.status === 200 && res.ok && res.text()) || Promise.reject())\n .then((text) => {\n if(text !== App.versionFull) {\n this.hasUpdate = true;\n clearInterval(checkUpdateInterval);\n\n if(!this.newBtnMenu.classList.contains('is-hidden')) {\n this.updateBtn.classList.remove('is-hidden');\n }\n }\n })\n .catch(noop);\n }, CHECK_UPDATE_INTERVAL);\n });\n\n const onResize = () => {\n const rect = this.rect = this.tabsContainer.getBoundingClientRect();\n document.documentElement.style.setProperty('--left-column-width', rect.width + 'px');\n };\n\n fastRaf(onResize);\n mediaSizes.addEventListener('resize', onResize);\n }\n\n private initSearch() {\n const searchContainer = this.sidebarEl.querySelector('#search-container') as HTMLDivElement;\n\n const scrollable = new Scrollable(searchContainer);\n\n const close = () => {\n // setTimeout(() => {\n simulateClickEvent(this.backBtn);\n // }, 0);\n };\n\n this.searchGroups = {\n contacts: new SearchGroup('SearchAllChatsShort', 'contacts', undefined, undefined, undefined, undefined, close),\n globalContacts: new SearchGroup('GlobalSearch', 'contacts', undefined, undefined, undefined, undefined, close),\n messages: new SearchGroup('SearchMessages', 'messages'),\n people: new SearchGroup(false, 'contacts', true, 'search-group-people', true, false, close, true),\n recent: new SearchGroup('Recent', 'contacts', true, 'search-group-recent', true, true, close)\n };\n\n const searchSuper = this.searchSuper = new AppSearchSuper({\n mediaTabs: [{\n inputFilter: 'inputMessagesFilterEmpty',\n name: 'FilterChats',\n type: 'chats'\n }, {\n inputFilter: 'inputMessagesFilterPhotoVideo',\n name: 'SharedMediaTab2',\n type: 'media'\n }, {\n inputFilter: 'inputMessagesFilterUrl',\n name: 'SharedLinksTab2',\n type: 'links'\n }, {\n inputFilter: 'inputMessagesFilterDocument',\n name: 'SharedFilesTab2',\n type: 'files'\n }, {\n inputFilter: 'inputMessagesFilterMusic',\n name: 'SharedMusicTab2',\n type: 'music'\n }, {\n inputFilter: 'inputMessagesFilterRoundVoice',\n name: 'SharedVoiceTab2',\n type: 'voice'\n }],\n scrollable,\n searchGroups: this.searchGroups,\n asChatList: true,\n hideEmptyTabs: false,\n showSender: true,\n managers: this.managers\n });\n\n searchContainer.prepend(searchSuper.nav.parentElement.parentElement);\n scrollable.container.append(searchSuper.container);\n\n const resetSearch = () => {\n searchSuper.setQuery({\n peerId: ''.toPeerId(),\n folderId: 0\n });\n searchSuper.selectTab(0);\n searchSuper.load(true);\n };\n\n resetSearch();\n\n const pickedElements: HTMLElement[] = [];\n let selectedPeerId: PeerId = ''.toPeerId();\n let selectedMinDate = 0;\n let selectedMaxDate = 0;\n const updatePicked = () => {\n // (this.inputSearch.input as HTMLInputElement).placeholder = pickedElements.length ? 'Search' : 'Telegram Search';\n this.inputSearch.container.classList.toggle('is-picked-twice', pickedElements.length === 2);\n this.inputSearch.container.classList.toggle('is-picked', !!pickedElements.length);\n\n if(pickedElements.length) {\n this.inputSearch.input.style.setProperty('--paddingLeft', (pickedElements[pickedElements.length - 1].getBoundingClientRect().right - this.inputSearch.input.getBoundingClientRect().left) + 'px');\n } else {\n this.inputSearch.input.style.removeProperty('--paddingLeft');\n }\n };\n\n const helper = document.createElement('div');\n helper.classList.add('search-helper');\n helper.addEventListener('click', (e) => {\n const target = findUpClassName(e.target, 'selector-user');\n if(!target) {\n return;\n }\n\n const key = target.dataset.key;\n if(key.indexOf('date_') === 0) {\n const [_, minDate, maxDate] = key.split('_');\n selectedMinDate = +minDate;\n selectedMaxDate = +maxDate;\n } else {\n selectedPeerId = key.toPeerId();\n }\n\n target.addEventListener('click', () => {\n unselectEntity(target);\n });\n\n this.inputSearch.container.append(target);\n this.inputSearch.onChange(this.inputSearch.value = '');\n pickedElements.push(target);\n updatePicked();\n });\n\n searchSuper.nav.parentElement.append(helper);\n\n const renderEntity = (key: PeerId | string, title?: string | HTMLElement) => {\n const div = document.createElement('div');\n div.classList.add('selector-user'/* , 'scale-in' */);\n\n const avatarEl = new AvatarElement();\n avatarEl.classList.add('selector-user-avatar', 'tgico', 'avatar-32');\n avatarEl.isDialog = true;\n\n div.dataset.key = '' + key;\n if(key.isPeerId()) {\n if(title === undefined) {\n title = new PeerTitle({peerId: key.toPeerId()}).element;\n }\n\n avatarEl.updateWithOptions({peerId: key as PeerId});\n } else {\n avatarEl.classList.add('tgico-calendarfilter');\n }\n\n if(title) {\n if(typeof(title) === 'string') {\n div.innerHTML = title;\n } else {\n replaceContent(div, title);\n div.append(title);\n }\n }\n\n div.insertAdjacentElement('afterbegin', avatarEl);\n\n return div;\n };\n\n const unselectEntity = (target: HTMLElement) => {\n const key = target.dataset.key;\n if(key.indexOf('date_') === 0) {\n selectedMinDate = selectedMaxDate = 0;\n } else {\n selectedPeerId = ''.toPeerId();\n }\n\n target.remove();\n indexOfAndSplice(pickedElements, target);\n\n setTimeout(() => {\n updatePicked();\n this.inputSearch.onChange(this.inputSearch.value);\n }, 0);\n };\n\n this.inputSearch.onClear = () => {\n pickedElements.forEach((el) => {\n unselectEntity(el);\n });\n };\n\n this.inputSearch.onChange = (value) => {\n searchSuper.cleanupHTML();\n searchSuper.setQuery({\n peerId: selectedPeerId,\n folderId: selectedPeerId ? undefined : 0,\n query: value,\n minDate: selectedMinDate,\n maxDate: selectedMaxDate\n });\n searchSuper.load(true);\n\n helper.replaceChildren();\n searchSuper.nav.classList.remove('hide');\n if(!value) {\n }\n\n if(!selectedPeerId && value.trim()) {\n const middleware = searchSuper.middleware.get();\n Promise.all([\n // appMessagesManager.getConversationsAll(value).then((dialogs) => dialogs.map((d) => d.peerId)),\n this.managers.dialogsStorage.getDialogs({query: value}).then(({dialogs}) => dialogs.map((d) => d.peerId)),\n this.managers.appUsersManager.getContactsPeerIds(value, true)\n ]).then((results) => {\n if(!middleware()) return;\n const peerIds = new Set(results[0].concat(results[1]));\n\n peerIds.forEach((peerId) => {\n helper.append(renderEntity(peerId));\n });\n\n searchSuper.nav.classList.toggle('hide', !!helper.innerHTML);\n // console.log('got peerIds by value:', value, [...peerIds]);\n });\n }\n\n if(!selectedMinDate && value.trim()) {\n const dates: DateData[] = [];\n fillTipDates(value, dates);\n dates.forEach((dateData) => {\n helper.append(renderEntity('date_' + dateData.minDate + '_' + dateData.maxDate, dateData.title));\n });\n\n searchSuper.nav.classList.toggle('hide', !!helper.innerHTML);\n }\n };\n\n searchSuper.tabs.inputMessagesFilterEmpty.addEventListener('mousedown', (e) => {\n const target = findUpTag(e.target, DIALOG_LIST_ELEMENT_TAG) as HTMLElement;\n if(!target) {\n return;\n }\n\n const searchGroup = findUpClassName(target, 'search-group');\n if(!searchGroup || searchGroup.classList.contains('search-group-recent') || searchGroup.classList.contains('search-group-people')) {\n return;\n }\n\n const peerId = target.getAttribute('data-peer-id').toPeerId();\n this.managers.appUsersManager.pushRecentSearch(peerId);\n }, {capture: true});\n\n const peopleContainer = document.createElement('div');\n peopleContainer.classList.add('search-group-scrollable');\n peopleContainer.append(this.searchGroups.people.list);\n this.searchGroups.people.container.append(peopleContainer);\n const peopleScrollable = new ScrollableX(peopleContainer);\n\n let first = true;\n let hideNewBtnMenuTimeout: number;\n // const transition = Transition.bind(null, searchContainer.parentElement, 150);\n const transition = TransitionSlider({\n content: searchContainer.parentElement,\n type: 'zoom-fade',\n transitionTime: 150,\n onTransitionEnd: (id) => {\n if(hideNewBtnMenuTimeout) clearTimeout(hideNewBtnMenuTimeout);\n\n if(id === 0 && !first) {\n searchSuper.selectTab(0, false);\n this.inputSearch.onClearClick();\n hideNewBtnMenuTimeout = window.setTimeout(() => {\n hideNewBtnMenuTimeout = 0;\n this.newBtnMenu.classList.remove('is-hidden');\n this.hasUpdate && this.updateBtn.classList.remove('is-hidden');\n }, 150);\n }\n\n first = false;\n }\n });\n\n transition(0);\n\n const activeClassName = 'is-visible';\n const onFocus = () => {\n this.toolsBtn.classList.remove(activeClassName);\n this.backBtn.classList.add(activeClassName);\n this.newBtnMenu.classList.add('is-hidden');\n this.updateBtn.classList.add('is-hidden');\n this.toolsBtn.parentElement.firstElementChild.classList.toggle('state-back', true);\n\n const navigationType: NavigationItem['type'] = 'global-search';\n if(!IS_MOBILE_SAFARI && !appNavigationController.findItemByType(navigationType)) {\n appNavigationController.pushItem({\n onPop: () => {\n close();\n },\n type: navigationType\n });\n }\n\n transition(1);\n };\n\n this.inputSearch.input.addEventListener('focus', onFocus);\n onFocus();\n\n attachClickEvent(this.backBtn, (e) => {\n this.toolsBtn.classList.add(activeClassName);\n this.backBtn.classList.remove(activeClassName);\n this.toolsBtn.parentElement.firstElementChild.classList.toggle('state-back', false);\n\n appNavigationController.removeByType('global-search');\n\n transition(0);\n });\n\n const clearRecentSearchBtn = ButtonIcon('close');\n this.searchGroups.recent.nameEl.append(clearRecentSearchBtn);\n clearRecentSearchBtn.addEventListener('click', () => {\n confirmationPopup({\n descriptionLangKey: 'Search.Confirm.ClearHistory',\n button: {\n langKey: 'ClearButton',\n isDanger: true\n }\n }).then(() => {\n return this.managers.appUsersManager.clearRecentSearch().then(() => {\n this.searchGroups.recent.clear();\n });\n });\n });\n }\n}\n\nexport class SettingChatListSection extends SettingSection {\n public sortedList: SortedUserList;\n\n constructor(options: SettingSectionOptions & {sortedList: SortedUserList}) {\n super(options);\n\n this.sortedList = options.sortedList;\n\n this.content.append(this.sortedList.list);\n }\n\n public makeButton(options: ButtonOptions) {\n const button = Button('folder-category-button btn btn-primary btn-transparent', options);\n if(this.title) this.content.insertBefore(button, this.title.nextSibling);\n else this.content.prepend(button);\n return button;\n }\n}\n\nconst appSidebarLeft = new AppSidebarLeft();\nMOUNT_CLASS_TO.appSidebarLeft = appSidebarLeft;\nexport default appSidebarLeft;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTab} from '../../slider';\nimport AppSelectPeers from '../../appSelectPeers';\nimport {setButtonLoader} from '../../putPreloader';\nimport {LangPackKey, _i18n} from '../../../lib/langPack';\nimport ButtonCorner from '../../buttonCorner';\n\nexport default class AppAddMembersTab extends SliderSuperTab {\n private nextBtn: HTMLButtonElement;\n private selector: AppSelectPeers;\n private peerType: 'channel' | 'chat' | 'privacy';\n private takeOut: (peerIds: PeerId[]) => Promise<any> | false | void;\n private skippable: boolean;\n\n public init(options: {\n title: LangPackKey,\n placeholder: LangPackKey,\n type: AppAddMembersTab['peerType'],\n takeOut?: AppAddMembersTab['takeOut'],\n skippable: boolean,\n selectedPeerIds?: PeerId[]\n }) {\n this.container.classList.add('add-members-container');\n this.nextBtn = ButtonCorner({icon: 'arrow_next'});\n this.content.append(this.nextBtn);\n this.scrollable.container.remove();\n\n this.nextBtn.addEventListener('click', () => {\n const peerIds = this.selector.getSelected().map((sel) => sel.toPeerId());\n const result = this.takeOut(peerIds);\n\n if(this.skippable && !(result instanceof Promise)) {\n this.close();\n } else if(result instanceof Promise) {\n this.attachToPromise(result);\n } else if(result === undefined) {\n this.close();\n }\n });\n\n //\n this.setTitle(options.title);\n this.peerType = options.type;\n this.takeOut = options.takeOut;\n this.skippable = options.skippable;\n\n const isPrivacy = this.peerType === 'privacy';\n this.selector = new AppSelectPeers({\n appendTo: this.content,\n onChange: this.skippable ? null : (length) => {\n this.nextBtn.classList.toggle('is-visible', !!length);\n },\n peerType: [isPrivacy ? 'dialogs' : 'contacts'],\n placeholder: options.placeholder,\n exceptSelf: isPrivacy,\n filterPeerTypeBy: isPrivacy ? ['isAnyGroup', 'isUser'] : undefined,\n managers: this.managers,\n design: 'square'\n });\n\n if(options.selectedPeerIds) {\n this.selector.addInitial(options.selectedPeerIds);\n }\n\n this.nextBtn.classList.add('tgico-arrow_next');\n this.nextBtn.replaceChildren();\n this.nextBtn.disabled = false;\n this.nextBtn.classList.toggle('is-visible', this.skippable);\n }\n\n public attachToPromise(promise: Promise<any>) {\n const removeLoader = setButtonLoader(this.nextBtn, 'arrow_next');\n\n promise.then(() => {\n this.close();\n }, () => {\n removeLoader();\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {renderImageFromUrlPromise} from './dom/renderImageFromUrl';\n\nexport function averageColorFromCanvas(canvas: HTMLCanvasElement) {\n const context = canvas.getContext('2d');\n\n const pixel = new Array(4).fill(0);\n const pixels = context.getImageData(0, 0, canvas.width, canvas.height).data;\n const pixelsLength = pixels.length / 4;\n for(let i = 0; i < pixels.length; i += 4) {\n // const alphaPixel = pixels[i + 3];\n pixel[0] += pixels[i]/* * (alphaPixel / 255) */;\n pixel[1] += pixels[i + 1]/* * (alphaPixel / 255) */;\n pixel[2] += pixels[i + 2]/* * (alphaPixel / 255) */;\n pixel[3] += pixels[i + 3];\n }\n\n const outPixel = new Uint8ClampedArray(4);\n outPixel[0] = pixel[0] / pixelsLength;\n outPixel[1] = pixel[1] / pixelsLength;\n outPixel[2] = pixel[2] / pixelsLength;\n outPixel[3] = pixel[3] / pixelsLength;\n // outPixel[3] = 255;\n return outPixel;\n}\n\nexport function averageColorFromImageSource(imageSource: CanvasImageSource, width: number, height: number) {\n const canvas = document.createElement('canvas');\n const ratio = width / height;\n const DIMENSIONS = 50;\n if(ratio === 1) {\n canvas.width = DIMENSIONS;\n canvas.height = canvas.width / ratio;\n } else if(ratio > 1) {\n canvas.height = DIMENSIONS;\n canvas.width = canvas.height / ratio;\n } else {\n canvas.width = canvas.height = DIMENSIONS;\n }\n\n const context = canvas.getContext('2d');\n context.drawImage(imageSource, 0, 0, width, height, 0, 0, canvas.width, canvas.height);\n return averageColorFromCanvas(canvas);\n}\n\nexport function averageColor(imageUrl: string) {\n const img = document.createElement('img');\n return renderImageFromUrlPromise(img, imageUrl, false).then(() => {\n return averageColorFromImageSource(img, img.naturalWidth, img.naturalHeight);\n });\n};\n","import {rgbaToHsla} from './color';\n\n// * https://github.com/TelegramMessenger/Telegram-iOS/blob/3d062fff78cc6b287c74e6171f855a3500c0156d/submodules/TelegramPresentationData/Sources/PresentationData.swift#L453\nexport default function highlightningColor(rgba: [number, number, number, number?]) {\n let {h, s, l} = rgbaToHsla(rgba[0], rgba[1], rgba[2]);\n if(s > 0) {\n s = Math.min(100, s + 5 + 0.1 * (100 - s));\n }\n l = Math.max(0, l * .65);\n\n const hsla = `hsla(${h}, ${s}%, ${l}%, .4)`;\n return hsla;\n}\n","import {ColorHsla, ColorRgba, hexaToHsla, hslaToRgba, rgbaToHexa as rgbaToHexa, rgbaToHsla} from '../helpers/color';\nimport attachGrabListeners from '../helpers/dom/attachGrabListeners';\nimport clamp from '../helpers/number/clamp';\nimport InputField, {InputState} from './inputField';\n\nexport type ColorPickerColor = {\n hsl: string;\n rgb: string;\n hex: string;\n hsla: string;\n rgba: string;\n hexa: string;\n rgbaArray: ColorRgba;\n};\n\nexport default class ColorPicker {\n private static BASE_CLASS = 'color-picker';\n public container: HTMLElement;\n\n private boxRect: DOMRect;\n // private boxDraggerRect: DOMRect;\n private hueRect: DOMRect;\n // private hueDraggerRect: DOMRect;\n\n private hue = 0;\n private saturation = 100;\n private lightness = 50;\n private alpha = 1;\n private elements: {\n box: SVGSVGElement,\n boxDragger: SVGSVGElement,\n sliders: HTMLElement,\n hue: SVGSVGElement,\n hueDragger: SVGSVGElement,\n saturation: SVGLinearGradientElement,\n } = {} as any;\n private hexInputField: InputField;\n private rgbInputField: InputField;\n public onChange: (color: ReturnType<ColorPicker['getCurrentColor']>) => void;\n\n constructor() {\n this.container = document.createElement('div');\n this.container.classList.add(ColorPicker.BASE_CLASS);\n\n const html = `\n <svg class=\"${ColorPicker.BASE_CLASS + '-box'}\" viewBox=\"0 0 380 198\">\n <defs>\n <linearGradient id=\"color-picker-saturation\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stop-color=\"#fff\"></stop>\n <stop offset=\"100%\" stop-color=\"hsl(0,100%,50%)\"></stop>\n </linearGradient>\n <linearGradient id=\"color-picker-brightness\" x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"rgba(0,0,0,0)\"></stop>\n <stop offset=\"100%\" stop-color=\"#000\"></stop>\n </linearGradient>\n <pattern id=\"color-picker-pattern\" width=\"100%\" height=\"100%\">\n <rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" fill=\"url(#color-picker-saturation)\"></rect>\n <rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" fill=\"url(#color-picker-brightness)\"></rect>\n </pattern>\n </defs>\n <rect rx=\"10\" ry=\"10\" x=\"0\" y=\"0\" width=\"380\" height=\"198\" fill=\"url(#color-picker-pattern)\"></rect>\n <svg class=\"${ColorPicker.BASE_CLASS + '-dragger'} ${ColorPicker.BASE_CLASS + '-box-dragger'}\" x=\"0\" y=\"0\">\n <circle r=\"11\" fill=\"inherit\" stroke=\"#fff\" stroke-width=\"2\"></circle>\n </svg>\n </svg>\n <div class=\"${ColorPicker.BASE_CLASS + '-sliders'}\">\n <svg class=\"${ColorPicker.BASE_CLASS + '-color-slider'}\" viewBox=\"0 0 380 24\">\n <defs>\n <linearGradient id=\"hue\" x1=\"100%\" y1=\"0%\" x2=\"0%\" y2=\"0%\">\n <stop offset=\"0%\" stop-color=\"#f00\"></stop>\n <stop offset=\"16.666%\" stop-color=\"#f0f\"></stop>\n <stop offset=\"33.333%\" stop-color=\"#00f\"></stop>\n <stop offset=\"50%\" stop-color=\"#0ff\"></stop>\n <stop offset=\"66.666%\" stop-color=\"#0f0\"></stop>\n <stop offset=\"83.333%\" stop-color=\"#ff0\"></stop>\n <stop offset=\"100%\" stop-color=\"#f00\"></stop>\n </linearGradient>\n </defs>\n <rect rx=\"4\" ry=\"4\" x=\"0\" y=\"9\" width=\"380\" height=\"8\" fill=\"url(#hue)\"></rect>\n <svg class=\"${ColorPicker.BASE_CLASS + '-dragger'} ${ColorPicker.BASE_CLASS + '-color-slider-dragger'}\" x=\"0\" y=\"13\">\n <circle r=\"11\" fill=\"inherit\" stroke=\"#fff\" stroke-width=\"2\"></circle>\n </svg>\n </svg>\n </div>\n `;\n\n this.container.innerHTML = html;\n\n this.elements.box = this.container.firstElementChild as any;\n this.elements.boxDragger = this.elements.box.lastElementChild as any;\n this.elements.saturation = this.elements.box.firstElementChild.firstElementChild as any;\n\n this.elements.sliders = this.elements.box.nextElementSibling as any;\n\n this.elements.hue = this.elements.sliders.firstElementChild as any;\n this.elements.hueDragger = this.elements.hue.lastElementChild as any;\n\n this.hexInputField = new InputField({plainText: true, label: 'Appearance.Color.Hex'});\n this.rgbInputField = new InputField({plainText: true, label: 'Appearance.Color.RGB'});\n\n const inputs = document.createElement('div');\n inputs.className = ColorPicker.BASE_CLASS + '-inputs';\n inputs.append(this.hexInputField.container, this.rgbInputField.container);\n this.container.append(inputs);\n\n this.hexInputField.input.addEventListener('input', () => {\n let value = this.hexInputField.value.replace(/#/g, '').slice(0, 6);\n\n const match = value.match(/([a-fA-F\\d]+)/);\n const valid = match && match[0].length === value.length && [/* 3, 4, */6].includes(value.length);\n this.hexInputField.setState(valid ? InputState.Neutral : InputState.Error);\n\n value = '#' + value;\n this.hexInputField.setValueSilently(value);\n\n if(valid) {\n this.setColor(value, false, true);\n }\n });\n\n // patched https://stackoverflow.com/a/34029238/6758968\n const rgbRegExp = /^(?:rgb)?\\(?([01]?\\d\\d?|2[0-4]\\d|25[0-5])(?:\\W+)([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\W+(?:([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\)?)$/;\n this.rgbInputField.input.addEventListener('input', () => {\n const match = this.rgbInputField.value.match(rgbRegExp);\n this.rgbInputField.setState(match ? InputState.Neutral : InputState.Error);\n\n if(match) {\n this.setColor(rgbaToHsla(+match[1], +match[2], +match[3]), true, false);\n }\n });\n\n this.attachBoxListeners();\n this.attachHueListeners();\n }\n\n private onGrabStart = () => {\n document.documentElement.style.cursor = this.elements.boxDragger.style.cursor = 'grabbing';\n };\n\n private onGrabEnd = () => {\n document.documentElement.style.cursor = this.elements.boxDragger.style.cursor = '';\n };\n\n private attachBoxListeners() {\n attachGrabListeners(this.elements.box as any, () => {\n this.onGrabStart();\n this.boxRect = this.elements.box.getBoundingClientRect();\n // this.boxDraggerRect = this.elements.boxDragger.getBoundingClientRect();\n }, (pos) => {\n this.saturationHandler(pos.x, pos.y);\n }, () => {\n this.onGrabEnd();\n });\n }\n\n private attachHueListeners() {\n attachGrabListeners(this.elements.hue as any, () => {\n this.onGrabStart();\n this.hueRect = this.elements.hue.getBoundingClientRect();\n // this.hueDraggerRect = this.elements.hueDragger.getBoundingClientRect();\n }, (pos) => {\n this.hueHandler(pos.x);\n }, () => {\n this.onGrabEnd();\n });\n }\n\n public setColor(color: ColorHsla | string, updateHexInput = true, updateRgbInput = true) {\n if(color === undefined) { // * set to red\n color = {\n h: 0,\n s: 100,\n l: 50,\n a: 1\n };\n } else if(typeof(color) === 'string') {\n if(color[0] === '#') {\n color = hexaToHsla(color);\n } else {\n const rgb = color.match(/[.?\\d]+/g);\n color = rgbaToHsla(+rgb[0], +rgb[1], +rgb[2], rgb[3] === undefined ? 1 : +rgb[3]);\n }\n }\n\n // Set box\n this.boxRect = this.elements.box.getBoundingClientRect();\n\n const boxX = this.boxRect.width / 100 * color.s;\n const percentY = 100 - (color.l / (100 - color.s / 2)) * 100;\n const boxY = this.boxRect.height / 100 * percentY;\n\n this.saturationHandler(this.boxRect.left + boxX, this.boxRect.top + boxY, false);\n\n // Set hue\n this.hueRect = this.elements.hue.getBoundingClientRect();\n\n const percentHue = color.h / 360;\n const hueX = this.hueRect.left + this.hueRect.width * percentHue;\n\n this.hueHandler(hueX, false);\n\n // Set values\n this.hue = color.h;\n this.saturation = color.s;\n this.lightness = color.l;\n this.alpha = color.a;\n\n this.updatePicker(updateHexInput, updateRgbInput);\n };\n\n public getCurrentColor(): ColorPickerColor {\n const rgbaArray = hslaToRgba(this.hue, this.saturation, this.lightness, this.alpha);\n const hexa = rgbaToHexa(rgbaArray);\n const hex = hexa.slice(0, -2);\n\n return {\n hsl: `hsl(${this.hue}, ${this.saturation}%, ${this.lightness}%)`,\n rgb: `rgb(${rgbaArray[0]}, ${rgbaArray[1]}, ${rgbaArray[2]})`,\n hex: hex,\n hsla: `hsla(${this.hue}, ${this.saturation}%, ${this.lightness}%, ${this.alpha})`,\n rgba: `rgba(${rgbaArray[0]}, ${rgbaArray[1]}, ${rgbaArray[2]}, ${rgbaArray[3]})`,\n hexa: hexa,\n rgbaArray: rgbaArray\n };\n }\n\n public updatePicker(updateHexInput = true, updateRgbInput = true) {\n const color = this.getCurrentColor();\n this.elements.boxDragger.setAttributeNS(null, 'fill', color.hex);\n\n if(updateHexInput) {\n this.hexInputField.setValueSilently(color.hex);\n this.hexInputField.setState(InputState.Neutral);\n }\n\n if(updateRgbInput) {\n this.rgbInputField.setValueSilently(color.rgbaArray.slice(0, -1).join(', '));\n this.rgbInputField.setState(InputState.Neutral);\n }\n\n if(this.onChange) {\n this.onChange(color);\n }\n }\n\n private hueHandler(pageX: number, update = true) {\n const eventX = clamp(pageX - this.hueRect.left, 0, this.hueRect.width);\n\n const percents = eventX / this.hueRect.width;\n this.hue = Math.round(360 * percents);\n\n const hsla = `hsla(${this.hue}, 100%, 50%, ${this.alpha})`;\n\n this.elements.hueDragger.setAttributeNS(null, 'x', (percents * 100) + '%');\n this.elements.hueDragger.setAttributeNS(null, 'fill', hsla);\n\n this.elements.saturation.lastElementChild.setAttributeNS(null, 'stop-color', hsla);\n\n if(update) {\n this.updatePicker();\n }\n }\n\n private saturationHandler(pageX: number, pageY: number, update = true) {\n const maxX = this.boxRect.width;\n const maxY = this.boxRect.height;\n\n const eventX = clamp(pageX - this.boxRect.left, 0, maxX);\n const eventY = clamp(pageY - this.boxRect.top, 0, maxY);\n\n const posX = eventX / maxX * 100;\n const posY = eventY / maxY * 100;\n\n const boxDragger = this.elements.boxDragger;\n boxDragger.setAttributeNS(null, 'x', posX + '%');\n boxDragger.setAttributeNS(null, 'y', posY + '%');\n\n const saturation = clamp(posX, 0, 100);\n\n const lightnessX = 100 - saturation / 2;\n const lightnessY = 100 - clamp(posY, 0, 100);\n\n const lightness = clamp(lightnessY / 100 * lightnessX, 0, 100);\n\n this.saturation = saturation;\n this.lightness = lightness;\n\n if(update) {\n this.updatePicker();\n }\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AppTheme} from '../../../config/state';\nimport {hexaToRgba} from '../../../helpers/color';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport findUpClassName from '../../../helpers/dom/findUpClassName';\nimport highlightningColor from '../../../helpers/highlightningColor';\nimport throttle from '../../../helpers/schedulers/throttle';\nimport themeController from '../../../helpers/themeController';\nimport appImManager from '../../../lib/appManagers/appImManager';\nimport rootScope from '../../../lib/rootScope';\nimport ColorPicker, {ColorPickerColor} from '../../colorPicker';\nimport SettingSection from '../../settingSection';\nimport {SliderSuperTab} from '../../slider';\nimport {WallPaper} from '../../../layer';\n\nexport default class AppBackgroundColorTab extends SliderSuperTab {\n private colorPicker: ColorPicker;\n private grid: HTMLElement;\n private applyColor: (hex: string, updateColorPicker?: boolean) => void;\n private theme: AppTheme;\n\n init() {\n this.container.classList.add('background-container', 'background-color-container');\n this.setTitle('SetColor');\n\n this.theme = themeController.getTheme();\n\n const section = new SettingSection({});\n this.colorPicker = new ColorPicker();\n\n section.content.append(this.colorPicker.container);\n\n this.scrollable.append(section.container);\n\n const gridSection = new SettingSection({});\n\n const grid = this.grid = document.createElement('div');\n grid.classList.add('grid');\n\n const colors = [\n '#E6EBEE',\n '#B2CEE1',\n '#008DD0',\n '#C6E7CB',\n '#C4E1A6',\n '#60B16E',\n '#CCD0AF',\n '#A6A997',\n '#7A7072',\n '#FDD7AF',\n '#FDB76E',\n '#DD8851'\n ];\n\n colors.forEach((color) => {\n const item = document.createElement('div');\n item.classList.add('grid-item');\n item.dataset.color = color.toLowerCase();\n\n // * need for transform scale\n const media = document.createElement('div');\n media.classList.add('grid-item-media');\n media.style.backgroundColor = color;\n\n item.append(media);\n grid.append(item);\n });\n\n attachClickEvent(grid, (e) => {\n const target = findUpClassName(e.target, 'grid-item');\n if(!target || target.classList.contains('active')) {\n return;\n }\n\n const color = target.dataset.color;\n if(!color) {\n return;\n }\n\n this.applyColor(color);\n }, {listenerSetter: this.listenerSetter});\n\n gridSection.content.append(grid);\n this.scrollable.append(gridSection.container);\n\n this.applyColor = throttle(this._applyColor, 16, true);\n }\n\n private setActive() {\n const active = this.grid.querySelector('.active');\n const background = this.theme.settings;\n const wallPaper = background.wallpaper;\n const color = wallPaper.settings.background_color;\n const target = color ? this.grid.querySelector(`.grid-item[data-color=\"${color}\"]`) : null;\n if(active === target) {\n return;\n }\n\n if(active) {\n active.classList.remove('active');\n }\n\n if(target) {\n target.classList.add('active');\n }\n }\n\n private _applyColor = (hex: string, updateColorPicker = true) => {\n if(updateColorPicker) {\n this.colorPicker.setColor(hex);\n } else {\n const rgba = hexaToRgba(hex);\n const settings = this.theme.settings;\n const hsla = highlightningColor(rgba);\n\n const wallPaper: WallPaper.wallPaperNoFile = {\n _: 'wallPaperNoFile',\n id: 0,\n pFlags: {},\n settings: {\n _: 'wallPaperSettings',\n background_color: parseInt(hex.slice(1), 16),\n pFlags: {}\n }\n };\n\n settings.wallpaper = wallPaper;\n settings.highlightningColor = hsla;\n\n this.managers.appStateManager.pushToState('settings', rootScope.settings);\n\n appImManager.applyCurrentTheme(undefined, undefined, true);\n this.setActive();\n }\n };\n\n private onColorChange = (color: ColorPickerColor) => {\n this.applyColor(color.hex, false);\n };\n\n onOpen() {\n setTimeout(() => {\n const settings = this.theme.settings;\n const color = settings?.wallpaper?.settings?.background_color;\n\n const isColored = !!color && settings.wallpaper._ === 'wallPaperNoFile';\n\n // * set active if type is color\n if(isColored) {\n this.colorPicker.onChange = this.onColorChange;\n }\n\n this.colorPicker.setColor((color && '#' + color.toString(16)) || '#cccccc');\n\n if(!isColored) {\n this.colorPicker.onChange = this.onColorChange;\n }\n }, 0);\n }\n\n onCloseAfterTimeout() {\n this.colorPicker.onChange = undefined;\n this.colorPicker = undefined;\n\n return super.onCloseAfterTimeout();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {averageColor, averageColorFromCanvas} from '../../../helpers/averageColor';\nimport blur from '../../../helpers/blur';\nimport deferredPromise, {CancellablePromise} from '../../../helpers/cancellablePromise';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport findUpClassName from '../../../helpers/dom/findUpClassName';\nimport highlightningColor from '../../../helpers/highlightningColor';\nimport copy from '../../../helpers/object/copy';\nimport sequentialDom from '../../../helpers/sequentialDom';\nimport ChatBackgroundGradientRenderer from '../../chat/gradientRenderer';\nimport {Document, PhotoSize, WallPaper, WebDocument} from '../../../layer';\nimport {MyDocument} from '../../../lib/appManagers/appDocsManager';\nimport appDownloadManager, {AppDownloadManager, DownloadBlob} from '../../../lib/appManagers/appDownloadManager';\nimport appImManager from '../../../lib/appManagers/appImManager';\nimport rootScope from '../../../lib/rootScope';\nimport Button from '../../button';\nimport CheckboxField from '../../checkboxField';\nimport ProgressivePreloader from '../../preloader';\nimport {SliderSuperTab} from '../../slider';\nimport AppBackgroundColorTab from './backgroundColor';\nimport choosePhotoSize from '../../../lib/appManagers/utils/photos/choosePhotoSize';\nimport {STATE_INIT, AppTheme} from '../../../config/state';\nimport themeController from '../../../helpers/themeController';\nimport requestFile from '../../../helpers/files/requestFile';\nimport {renderImageFromUrlPromise} from '../../../helpers/dom/renderImageFromUrl';\nimport scaleMediaElement from '../../../helpers/canvas/scaleMediaElement';\nimport {MediaSize} from '../../../helpers/mediaSize';\nimport wrapPhoto from '../../wrappers/photo';\nimport {CreateRowFromCheckboxField} from '../../row';\nimport {generateSection} from '../../settingSection';\nimport {getColorsFromWallPaper} from '../../../helpers/color';\n\nexport default class AppBackgroundTab extends SliderSuperTab {\n public static tempId = 0;\n private grid: HTMLElement;\n private clicked: Set<DocId> = new Set();\n private blurCheckboxField: CheckboxField;\n\n private wallPapersByElement: Map<HTMLElement, WallPaper> = new Map();\n private elementsByKey: Map<string, HTMLElement> = new Map();\n\n public static getInitArgs() {\n return {\n backgrounds: rootScope.managers.appThemesManager.getWallPapers()\n };\n }\n\n private get theme() {\n return themeController.getTheme();\n }\n\n public init(p: ReturnType<typeof AppBackgroundTab['getInitArgs']> = AppBackgroundTab.getInitArgs()) {\n this.container.classList.add('background-container', 'background-image-container');\n this.setTitle('ChatBackground');\n\n {\n const container = generateSection(this.scrollable);\n\n const uploadButton = Button('btn-primary btn-transparent', {icon: 'cameraadd', text: 'ChatBackground.UploadWallpaper'});\n const colorButton = Button('btn-primary btn-transparent', {icon: 'colorize', text: 'SetColor'});\n const resetButton = Button('btn-primary btn-transparent', {icon: 'favourites', text: 'Appearance.Reset'});\n\n attachClickEvent(uploadButton, this.onUploadClick, {listenerSetter: this.listenerSetter});\n\n attachClickEvent(colorButton, () => {\n this.slider.createTab(AppBackgroundColorTab).open();\n }, {listenerSetter: this.listenerSetter});\n\n attachClickEvent(resetButton, this.onResetClick, {listenerSetter: this.listenerSetter});\n\n const wallPaper = this.theme.settings?.wallpaper;\n const blurCheckboxField = this.blurCheckboxField = new CheckboxField({\n text: 'ChatBackground.Blur',\n name: 'blur',\n checked: (wallPaper as WallPaper.wallPaper)?.settings?.pFlags?.blur\n });\n\n this.listenerSetter.add(blurCheckboxField.input)('change', async() => {\n this.theme.settings.wallpaper.settings.pFlags.blur = blurCheckboxField.input.checked || undefined;\n await this.managers.appStateManager.pushToState('settings', rootScope.settings);\n\n // * wait for animation end\n setTimeout(() => {\n const active = grid.querySelector('.active') as HTMLElement;\n if(!active) return;\n\n const wallpaper = this.wallPapersByElement.get(active);\n if((wallpaper as WallPaper.wallPaper).pFlags.pattern || wallpaper._ === 'wallPaperNoFile') {\n return;\n }\n\n AppBackgroundTab.setBackgroundDocument(wallpaper);\n }, 100);\n });\n\n container.append(\n uploadButton,\n colorButton,\n resetButton,\n CreateRowFromCheckboxField(blurCheckboxField).container\n );\n }\n\n rootScope.addEventListener('background_change', this.setActive);\n\n const promise = p.backgrounds.then((wallPapers) => {\n const promises = wallPapers.map((wallPaper) => {\n return this.addWallPaper(wallPaper);\n });\n\n return Promise.all(promises);\n });\n\n const gridContainer = generateSection(this.scrollable);\n const grid = this.grid = document.createElement('div');\n grid.classList.add('grid');\n attachClickEvent(grid, this.onGridClick, {listenerSetter: this.listenerSetter});\n gridContainer.append(grid);\n\n return promise;\n }\n\n private onUploadClick = () => {\n requestFile('image/x-png,image/png,image/jpeg').then(async(file) => {\n if(file.name.endsWith('.png')) {\n const img = document.createElement('img');\n const url = URL.createObjectURL(file);\n await renderImageFromUrlPromise(img, url, false);\n const mimeType = 'image/jpeg';\n const {blob} = await scaleMediaElement({media: img, size: new MediaSize(img.naturalWidth, img.naturalHeight), mimeType});\n file = new File([blob], file.name.replace(/\\.png$/, '.jpg'), {type: mimeType});\n }\n\n const wallPaper = await this.managers.appDocsManager.prepareWallPaperUpload(file);\n const uploadPromise = this.managers.appDocsManager.uploadWallPaper(wallPaper.id);\n const uploadDeferred: CancellablePromise<any> = appDownloadManager.getNewDeferredForUpload(file.name, uploadPromise);\n\n const deferred = deferredPromise<void>();\n deferred.addNotifyListener = uploadDeferred.addNotifyListener;\n deferred.cancel = uploadDeferred.cancel;\n\n uploadDeferred.then((wallPaper) => {\n this.clicked.delete(key);\n this.elementsByKey.delete(key);\n this.wallPapersByElement.set(container, wallPaper);\n const newKey = this.getWallPaperKey(wallPaper);\n this.elementsByKey.set(newKey, container);\n\n AppBackgroundTab.setBackgroundDocument(wallPaper).then(deferred.resolve, deferred.reject);\n }, deferred.reject);\n\n const key = this.getWallPaperKey(wallPaper);\n deferred.catch(() => {\n container.remove();\n });\n\n const preloader = new ProgressivePreloader({\n isUpload: true,\n cancelable: true,\n tryAgainOnFail: false\n });\n\n const {container} = await this.addWallPaper(wallPaper, false);\n this.clicked.add(key);\n\n preloader.attach(container, false, deferred);\n });\n };\n\n private onResetClick = () => {\n const defaultTheme = STATE_INIT.settings.themes.find((t) => t.name === this.theme.name);\n if(defaultTheme) {\n ++AppBackgroundTab.tempId;\n this.theme.settings = copy(defaultTheme.settings);\n this.managers.appStateManager.pushToState('settings', rootScope.settings);\n appImManager.applyCurrentTheme(undefined, undefined, true);\n this.blurCheckboxField.setValueSilently(this.theme.settings?.wallpaper?.settings?.pFlags?.blur);\n }\n };\n\n private getWallPaperKey(wallPaper: WallPaper) {\n return '' + wallPaper.id;\n }\n\n private getWallPaperKeyFromTheme(theme: AppTheme) {\n return '' + (this.getWallPaperKey(theme.settings?.wallpaper) || '');\n }\n\n public static addWallPaper(\n wallPaper: WallPaper,\n container = document.createElement('div')\n ) {\n const colors = getColorsFromWallPaper(wallPaper);\n const hasFile = wallPaper._ === 'wallPaper';\n if((hasFile && wallPaper.pFlags.pattern && !colors)/* ||\n (wallpaper.document as MyDocument).mime_type.indexOf('application/') === 0 */) {\n return;\n }\n\n const isDark = !!wallPaper.pFlags.dark;\n\n let doc: WebDocument.webDocumentNoProxy | Document.document = hasFile ? wallPaper.document as Document.document : undefined;\n if(hasFile && !doc) {\n doc = {\n _: 'webDocumentNoProxy',\n attributes: [],\n size: 100000,\n url: 'assets/img/pattern.svg',\n w: 1440,\n h: 2960,\n mime_type: 'image/svg+xml'\n };\n }\n\n container.classList.add('background-item');\n container.dataset.id = '' + wallPaper.id;\n\n const media = document.createElement('div');\n media.classList.add('background-item-media');\n\n const loadPromises: Promise<any>[] = [];\n let wrapped: ReturnType<typeof wrapPhoto>, size: ReturnType<typeof choosePhotoSize>;\n if(hasFile) {\n size = choosePhotoSize(doc, 200, 200);\n wrapped = wrapPhoto({\n photo: doc,\n message: null,\n container: media,\n withoutPreloader: true,\n size,\n noFadeIn: wallPaper.pFlags.pattern\n });\n\n if(wallPaper.pFlags.pattern) {\n media.classList.add('is-pattern');\n }\n\n const promise = wrapped.then(async({loadPromises, images}) => {\n await loadPromises.thumb || loadPromises.full;\n return images;\n }).then((images) => {\n if(wallPaper.pFlags.pattern) {\n if(isDark) {\n images.full.style.display = 'none';\n if(images.thumb) {\n images.thumb.style.display = 'none';\n }\n } else if(wallPaper.settings?.intensity) {\n images.full.style.opacity = '' + Math.abs(wallPaper.settings.intensity) / 100;\n }\n }\n\n return sequentialDom.mutate(() => {\n container.append(media);\n });\n });\n\n loadPromises.push(promise);\n } else {\n container.append(media);\n }\n\n if(wallPaper.settings?.background_color) {\n const {canvas} = ChatBackgroundGradientRenderer.create(colors);\n canvas.classList.add('background-colors-canvas');\n\n if(isDark && hasFile) {\n const promise = wrapped.then(({loadPromises}) => {\n return loadPromises.full.then(async() => {\n const cacheContext = await rootScope.managers.thumbsStorage.getCacheContext(doc, size.type);\n canvas.style.webkitMaskImage = `url(${cacheContext.url})`;\n canvas.style.opacity = '' + (wallPaper.pFlags.dark ? 100 + wallPaper.settings.intensity : wallPaper.settings.intensity) / 100;\n media.append(canvas);\n });\n });\n\n loadPromises.push(promise);\n } else {\n media.append(canvas);\n }\n }\n\n return {\n container,\n media,\n loadPromise: Promise.all(loadPromises)\n };\n }\n\n private addWallPaper(wallPaper: WallPaper, append = true) {\n const result = AppBackgroundTab.addWallPaper(wallPaper);\n if(result) {\n const {container, media} = result;\n container.classList.add('grid-item');\n media.classList.add('grid-item-media');\n\n const key = this.getWallPaperKey(wallPaper);\n this.wallPapersByElement.set(container, wallPaper);\n this.elementsByKey.set(key, container);\n\n if(this.getWallPaperKeyFromTheme(this.theme) === key) {\n container.classList.add('active');\n }\n\n this.grid[append ? 'append' : 'prepend'](container);\n }\n\n return result && result.loadPromise.then(() => result);\n }\n\n private onGridClick = (e: MouseEvent | TouchEvent) => {\n const target = findUpClassName(e.target, 'grid-item') as HTMLElement;\n if(!target) return;\n\n const wallpaper = this.wallPapersByElement.get(target);\n if(wallpaper._ === 'wallPaperNoFile') {\n AppBackgroundTab.setBackgroundDocument(wallpaper);\n return;\n }\n\n const key = this.getWallPaperKey(wallpaper);\n if(this.clicked.has(key)) return;\n this.clicked.add(key);\n\n const doc = wallpaper.document as MyDocument;\n const preloader = new ProgressivePreloader({\n cancelable: true,\n tryAgainOnFail: false\n });\n\n const load = async() => {\n const promise = AppBackgroundTab.setBackgroundDocument(wallpaper);\n const cacheContext = await this.managers.thumbsStorage.getCacheContext(doc);\n if(!cacheContext.url || this.theme.settings?.wallpaper?.settings?.pFlags?.blur) {\n preloader.attach(target, true, promise);\n }\n };\n\n preloader.construct();\n\n attachClickEvent(target, (e) => {\n if(preloader.preloader.parentElement) {\n preloader.onClick(e);\n preloader.detach();\n } else {\n load();\n }\n }, {listenerSetter: this.listenerSetter});\n\n load();\n\n // console.log(doc);\n };\n\n public static setBackgroundDocument = (wallPaper: WallPaper, themeSettings?: AppTheme['settings']) => {\n const _tempId = ++this.tempId;\n const middleware = () => _tempId === this.tempId;\n\n const doc = (wallPaper as WallPaper.wallPaper).document as MyDocument;\n const deferred = deferredPromise<void>();\n let download: Promise<void> | ReturnType<AppDownloadManager['downloadMediaURL']>;\n if(doc) {\n download = appDownloadManager.downloadMediaURL({\n media: doc,\n queueId: appImManager.chat.bubbles ? appImManager.chat.bubbles.lazyLoadQueue.queueId : 0\n });\n deferred.addNotifyListener = download.addNotifyListener;\n deferred.cancel = download.cancel;\n } else {\n download = Promise.resolve();\n }\n\n const saveToCache = (slug: string, url: string) => {\n fetch(url).then((response) => {\n appImManager.cacheStorage.save('backgrounds/' + slug, response);\n });\n };\n\n download.then(async() => {\n if(!middleware()) {\n deferred.resolve();\n return;\n }\n\n const hadSettings = !!themeSettings;\n themeSettings ??= themeController.getTheme().settings;\n const onReady = (url?: string) => {\n let getPixelPromise: Promise<Uint8ClampedArray>;\n const backgroundColor = getColorsFromWallPaper(wallPaper);\n if(url && !backgroundColor) {\n getPixelPromise = averageColor(url);\n } else {\n const {canvas} = ChatBackgroundGradientRenderer.create(backgroundColor);\n getPixelPromise = Promise.resolve(averageColorFromCanvas(canvas));\n }\n\n const slug = (wallPaper as WallPaper.wallPaper).slug ?? '';\n Promise.all([\n getPixelPromise,\n slug && saveToCache(slug, url)\n ]).then(([pixel]) => {\n if(!middleware()) {\n deferred.resolve();\n return;\n }\n\n const hsla = highlightningColor(Array.from(pixel) as any);\n\n themeSettings.wallpaper = wallPaper;\n themeSettings.highlightningColor = hsla;\n\n if(!hadSettings) {\n rootScope.managers.appStateManager.pushToState('settings', rootScope.settings);\n }\n\n appImManager.applyCurrentTheme(slug, url, true).then(deferred.resolve);\n });\n };\n\n if(!doc) {\n onReady();\n return;\n }\n\n const cacheContext = await rootScope.managers.thumbsStorage.getCacheContext(doc);\n if(themeSettings.wallpaper?.settings?.pFlags?.blur) {\n setTimeout(() => {\n const {canvas, promise} = blur(cacheContext.url, 12, 4);\n promise.then(() => {\n if(!middleware()) {\n deferred.resolve();\n return;\n }\n\n onReady(canvas.toDataURL());\n });\n }, 200);\n } else if(middleware()) {\n onReady(cacheContext.url);\n }\n });\n\n return deferred;\n };\n\n private setActive = () => {\n const active = this.grid.querySelector('.active');\n const target = this.elementsByKey.get(this.getWallPaperKeyFromTheme(this.theme));\n if(active === target) {\n return;\n }\n\n if(active) {\n active.classList.remove('active');\n }\n\n if(target) {\n target.classList.add('active');\n }\n };\n}\n","export default function requestFile(accept?: string) {\n const input = document.createElement('input');\n input.type = 'file';\n input.style.display = 'none';\n\n if(accept) {\n input.accept = accept;\n }\n\n document.body.append(input);\n\n const promise = new Promise<File>((resolve, reject) => {\n input.addEventListener('change', (e: any) => {\n const file: File = e.target.files[0];\n if(!file) {\n reject('NO_FILE_SELECTED');\n return;\n }\n\n resolve(file);\n }, {once: true});\n }).finally(() => {\n input.remove();\n });\n\n input.click();\n\n return promise;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTab} from '../../slider';\nimport AppSelectPeers from '../../appSelectPeers';\nimport appDialogsManager from '../../../lib/appManagers/appDialogsManager';\nimport {MyDialogFilter as DialogFilter} from '../../../lib/storages/filters';\nimport ButtonIcon from '../../buttonIcon';\nimport CheckboxField from '../../checkboxField';\nimport Button from '../../button';\nimport AppEditFolderTab from './editFolder';\nimport I18n, {i18n, LangPackKey, _i18n, join} from '../../../lib/langPack';\nimport {toast} from '../../toast';\nimport copy from '../../../helpers/object/copy';\nimport forEachReverse from '../../../helpers/array/forEachReverse';\nimport setInnerHTML from '../../../helpers/dom/setInnerHTML';\nimport wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';\nimport {REAL_FOLDERS} from '../../../lib/mtproto/mtproto_config';\nimport rootScope from '../../../lib/rootScope';\nimport {MTAppConfig} from '../../../lib/mtproto/appConfig';\nimport {attachClickEvent, simulateClickEvent} from '../../../helpers/dom/clickEvent';\nimport SettingSection from '../../settingSection';\n\nexport default class AppIncludedChatsTab extends SliderSuperTab {\n private editFolderTab: AppEditFolderTab;\n private confirmBtn: HTMLElement;\n\n private selector: AppSelectPeers;\n private type: 'included' | 'excluded';\n private filter: DialogFilter;\n private originalFilter: DialogFilter;\n\n private dialogsByFilters: Map<DialogFilter, Set<PeerId>>;\n private limit: number;\n\n public init(\n filter: DialogFilter,\n type: 'included' | 'excluded',\n editFolderTab: AppIncludedChatsTab['editFolderTab']\n ) {\n this.originalFilter = filter;\n this.filter = copy(this.originalFilter);\n this.type = type;\n this.editFolderTab = editFolderTab;\n\n this.content.remove();\n this.container.classList.add('included-chatlist-container');\n this.confirmBtn = ButtonIcon('check btn-confirm blue', {noRipple: true});\n this.confirmBtn.style.display = 'none';\n\n this.header.append(this.confirmBtn);\n\n attachClickEvent(this.confirmBtn, async() => {\n const selected = this.selector.getSelected();\n\n // this.filter.pFlags = {};\n\n if(this.type === 'included') {\n for(const key in this.filter.pFlags) {\n if(key.indexOf('exclude_') === 0) {\n continue;\n }\n\n // @ts-ignore\n delete this.filter.pFlags[key];\n }\n } else {\n for(const key in this.filter.pFlags) {\n if(key.indexOf('exclude_') !== 0) {\n continue;\n }\n\n // @ts-ignore\n delete this.filter.pFlags[key];\n }\n }\n\n const peerIds: PeerId[] = [];\n for(const key of selected) {\n if(key.isPeerId()) {\n peerIds.push(key.toPeerId());\n } else {\n // @ts-ignore\n this.filter.pFlags[key] = true;\n }\n }\n\n let cmp: (peerId: PeerId) => boolean;\n if(this.type === 'included') {\n cmp = (peerId) => peerIds.includes(peerId);\n } else {\n cmp = (peerId) => !peerIds.includes(peerId);\n }\n\n forEachReverse(this.filter.pinnedPeerIds, (peerId, idx) => {\n if(!cmp(peerId)) {\n this.filter.pinnedPeerIds.splice(idx, 1);\n this.filter.pinned_peers.splice(idx, 1);\n }\n });\n\n const other = this.type === 'included' ? 'excludePeerIds' : 'includePeerIds';\n const otherLegacy = this.type === 'included' ? 'exclude_peers' : 'include_peers';\n forEachReverse(this.filter[other], (peerId, idx) => {\n if(peerIds.includes(peerId)) {\n this.filter[other].splice(idx, 1);\n this.filter[otherLegacy].splice(idx, 1);\n }\n });\n\n this.filter[this.type === 'included' ? 'includePeerIds' : 'excludePeerIds'] = peerIds;\n this.filter[this.type === 'included' ? 'include_peers' : 'exclude_peers'] = await Promise.all(peerIds.map((peerId) => this.managers.appPeersManager.getInputPeerById(peerId)));\n // this.filter.pinned_peers = this.filter.pinned_peers.filter((peerId) => this.filter.include_peers.includes(peerId));\n\n this.editFolderTab.setFilter(this.filter, false);\n this.close();\n }, {listenerSetter: this.listenerSetter});\n\n const onAppConfig = (appConfig: MTAppConfig) => {\n this.limit = rootScope.premium ? appConfig.dialog_filters_chats_limit_premium : appConfig.dialog_filters_chats_limit_default;\n };\n\n this.listenerSetter.add(rootScope)('app_config', onAppConfig);\n\n this.dialogsByFilters = new Map();\n return Promise.all([\n this.managers.filtersStorage.getDialogFilters().then(async(filters) => {\n await Promise.all(filters.filter((filter) => !REAL_FOLDERS.has(filter.id)).map(async(filter) => {\n const dialogs = await this.managers.dialogsStorage.getFolderDialogs(filter.id);\n const peerIds = dialogs.map((d) => d.peerId);\n this.dialogsByFilters.set(filter, new Set(peerIds));\n }));\n }),\n\n this.managers.apiManager.getAppConfig().then((appConfig) => {\n onAppConfig(appConfig);\n })\n ]);\n }\n\n checkbox(selected?: boolean) {\n const checkboxField = new CheckboxField({\n round: true\n });\n if(selected) {\n checkboxField.input.checked = selected;\n }\n\n return checkboxField.label;\n }\n\n renderResults = async(peerIds: PeerId[]) => {\n // const other = this.type === 'included' ? this.filter.exclude_peers : this.filter.include_peers;\n\n await this.managers.appUsersManager.getContacts();\n peerIds.forEach((peerId) => {\n // if(other.includes(peerId)) return;\n\n const {dom} = appDialogsManager.addDialogNew({\n peerId: peerId,\n container: this.selector.scrollable,\n rippleEnabled: true,\n avatarSize: 'abitbigger'\n });\n\n const selected = this.selector.selected.has(peerId);\n dom.containerEl.append(this.checkbox(selected));\n // if(selected) dom.listEl.classList.add('active');\n\n const foundInFilters: HTMLElement[] = [];\n this.dialogsByFilters.forEach((dialogs, filter) => {\n if(dialogs.has(peerId)) {\n const span = document.createElement('span');\n setInnerHTML(span, wrapEmojiText(filter.title));\n foundInFilters.push(span);\n }\n });\n\n const joined = join(foundInFilters, false);\n joined.forEach((el) => {\n dom.lastMessageSpan.append(el);\n });\n });\n };\n\n onOpen() {\n this.confirmBtn.style.display = this.type === 'excluded' ? '' : 'none';\n this.setTitle(this.type === 'included' ? 'FilterAlwaysShow' : 'FilterNeverShow');\n\n const filter = this.filter;\n\n const categoriesSection = new SettingSection({\n noDelimiter: true,\n name: 'FilterChatTypes'\n });\n\n categoriesSection.container.classList.add('folder-categories');\n\n let details: {[flag: string]: {ico: string, text: LangPackKey}};\n if(this.type === 'excluded') {\n details = {\n exclude_muted: {ico: 'mute', text: 'ChatList.Filter.MutedChats'},\n exclude_archived: {ico: 'archive', text: 'ChatList.Filter.Archive'},\n exclude_read: {ico: 'readchats', text: 'ChatList.Filter.ReadChats'}\n };\n } else {\n details = {\n contacts: {ico: 'newprivate', text: 'ChatList.Filter.Contacts'},\n non_contacts: {ico: 'noncontacts', text: 'ChatList.Filter.NonContacts'},\n groups: {ico: 'group', text: 'ChatList.Filter.Groups'},\n broadcasts: {ico: 'newchannel', text: 'ChatList.Filter.Channels'},\n bots: {ico: 'bots', text: 'ChatList.Filter.Bots'}\n };\n }\n\n const f = document.createDocumentFragment();\n for(const key in details) {\n const button = Button('btn-primary btn-transparent folder-category-button', {icon: details[key].ico, text: details[key].text});\n button.dataset.peerId = key;\n button.append(this.checkbox());\n f.append(button);\n }\n categoriesSection.content.append(f);\n\n // ///////////////\n\n const selectedPeers = (this.type === 'included' ? filter.includePeerIds : filter.excludePeerIds).slice();\n\n this.selector = new AppSelectPeers({\n appendTo: this.container,\n onChange: this.onSelectChange,\n peerType: ['dialogs'],\n renderResultsFunc: this.renderResults,\n placeholder: 'Search',\n sectionNameLangPackKey: 'FilterChats',\n managers: this.managers\n });\n this.selector.selected = new Set(selectedPeers);\n\n let addedInitial = false;\n const _add = this.selector.add.bind(this.selector);\n this.selector.add = (peerId, title, scroll) => {\n if(this.selector.selected.size >= this.limit && addedInitial && !details[peerId]) {\n const el: HTMLInputElement = this.selector.list.querySelector(`[data-peer-id=\"${peerId}\"] [type=\"checkbox\"]`);\n if(el) {\n setTimeout(() => {\n el.checked = false;\n }, 0);\n }\n\n const str = I18n.format(this.type === 'excluded' ? 'ChatList.Filter.Exclude.LimitReached': 'ChatList.Filter.Include.LimitReached', true);\n toast(str);\n return;\n }\n\n const div = _add(peerId, details[peerId] ? i18n(details[peerId].text) : undefined, scroll);\n if(details[peerId]) {\n div.querySelector('avatar-element').classList.add('tgico-' + details[peerId].ico);\n }\n return div;\n };\n\n this.selector.scrollable.container.append(categoriesSection.container, this.selector.scrollable.container.lastElementChild);\n\n this.selector.addInitial(selectedPeers);\n addedInitial = true;\n\n for(const flag in filter.pFlags) {\n // @ts-ignore\n if(details.hasOwnProperty(flag) && !!filter.pFlags[flag]) {\n simulateClickEvent(categoriesSection.content.querySelector(`[data-peer-id=\"${flag}\"]`) as HTMLElement);\n }\n }\n }\n\n onSelectChange = (length: number) => {\n // const changed = !deepEqual(this.filter, this.originalFilter);\n if(this.type === 'included') {\n this.confirmBtn.style.display = length ? '' : 'none';\n }\n };\n\n onCloseAfterTimeout() {\n if(this.selector) {\n this.selector.container.remove();\n this.selector = null;\n }\n\n return super.onCloseAfterTimeout();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport appDialogsManager from '../../../lib/appManagers/appDialogsManager';\nimport {MyDialogFilter as DialogFilter} from '../../../lib/storages/filters';\nimport lottieLoader, {LottieLoader} from '../../../lib/rlottie/lottieLoader';\nimport {SliderSuperTab} from '../../slider';\nimport {toast} from '../../toast';\nimport InputField from '../../inputField';\nimport ButtonIcon from '../../buttonIcon';\nimport ButtonMenuToggle from '../../buttonMenuToggle';\nimport {ButtonMenuItemOptions} from '../../buttonMenu';\nimport Button from '../../button';\nimport AppIncludedChatsTab from './includedChats';\nimport {i18n, LangPackKey} from '../../../lib/langPack';\nimport PopupPeer from '../../popups/peer';\nimport RLottiePlayer from '../../../lib/rlottie/rlottiePlayer';\nimport copy from '../../../helpers/object/copy';\nimport deepEqual from '../../../helpers/object/deepEqual';\nimport wrapDraftText from '../../../lib/richTextProcessor/wrapDraftText';\nimport filterAsync from '../../../helpers/array/filterAsync';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport SettingSection from '../../settingSection';\nimport PopupElement from '../../popups';\n\nconst MAX_FOLDER_NAME_LENGTH = 12;\n\nexport default class AppEditFolderTab extends SliderSuperTab {\n private caption: HTMLElement;\n private stickerContainer: HTMLElement;\n\n private confirmBtn: HTMLElement;\n private menuBtn: HTMLElement;\n private nameInputField: InputField;\n\n private includePeerIds: SettingSection;\n private excludePeerIds: SettingSection;\n private flags: {[k in 'contacts' | 'non_contacts' | 'groups' | 'broadcasts' | 'bots' | 'exclude_muted' | 'exclude_archived' | 'exclude_read']: HTMLElement} = {} as any;\n\n private animation: RLottiePlayer;\n private filter: DialogFilter;\n private originalFilter: DialogFilter;\n\n private type: 'edit' | 'create';\n private loadAnimationPromise: ReturnType<LottieLoader['waitForFirstFrame']>;\n\n public static getInitArgs() {\n return {\n animationData: lottieLoader.loadAnimationFromURLManually('Folders_2')\n };\n }\n\n public init(p: ReturnType<typeof AppEditFolderTab['getInitArgs']> = AppEditFolderTab.getInitArgs()) {\n this.container.classList.add('edit-folder-container');\n this.caption = document.createElement('div');\n this.caption.classList.add('caption');\n this.caption.append(i18n('FilterIncludeExcludeInfo'));\n this.stickerContainer = document.createElement('div');\n this.stickerContainer.classList.add('sticker-container');\n\n this.confirmBtn = ButtonIcon('check btn-confirm hide blue');\n let deleting = false;\n const deleteFolderButton: ButtonMenuItemOptions = {\n icon: 'delete danger',\n text: 'FilterMenuDelete',\n onClick: () => {\n PopupElement.createPopup(PopupPeer, 'filter-delete', {\n titleLangKey: 'ChatList.Filter.Confirm.Remove.Header',\n descriptionLangKey: 'ChatList.Filter.Confirm.Remove.Text',\n buttons: [{\n langKey: 'Delete',\n callback: () => {\n if(deleting) {\n return;\n }\n\n deleting = true;\n\n this.managers.filtersStorage.updateDialogFilter(this.filter, true).then((bool) => {\n this.close();\n }).finally(() => {\n deleting = false;\n });\n },\n isDanger: true\n }]\n }).show();\n }\n };\n this.menuBtn = ButtonMenuToggle({\n listenerSetter: this.listenerSetter,\n direction: 'bottom-left',\n buttons: [deleteFolderButton]\n });\n this.menuBtn.classList.add('hide');\n\n this.header.append(this.confirmBtn, this.menuBtn);\n\n const inputSection = new SettingSection({});\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n this.nameInputField = new InputField({\n label: 'FilterNameHint',\n maxLength: MAX_FOLDER_NAME_LENGTH\n });\n\n inputWrapper.append(this.nameInputField.container);\n inputSection.content.append(inputWrapper);\n\n const generateList = (className: string, h2Text: LangPackKey, buttons: {icon: string, name?: string, withRipple?: true, text: LangPackKey}[], to: any) => {\n const section = new SettingSection({\n name: h2Text,\n noDelimiter: true\n });\n\n section.container.classList.add('folder-list', className);\n\n const categories = section.generateContentElement();\n categories.classList.add('folder-categories');\n\n buttons.forEach((o) => {\n const button = Button('folder-category-button btn btn-primary btn-transparent', {\n icon: o.icon,\n text: o.text,\n noRipple: o.withRipple ? undefined : true\n });\n\n if(o.name) {\n to[o.name] = button;\n }\n\n categories.append(button);\n });\n\n return section;\n };\n\n this.includePeerIds = generateList('folder-list-included', 'FilterInclude', [{\n icon: 'add primary',\n text: 'ChatList.Filter.Include.AddChat',\n withRipple: true\n }, {\n text: 'ChatList.Filter.Contacts',\n icon: 'newprivate',\n name: 'contacts'\n }, {\n text: 'ChatList.Filter.NonContacts',\n icon: 'noncontacts',\n name: 'non_contacts'\n }, {\n text: 'ChatList.Filter.Groups',\n icon: 'group',\n name: 'groups'\n }, {\n text: 'ChatList.Filter.Channels',\n icon: 'channel',\n name: 'broadcasts'\n }, {\n text: 'ChatList.Filter.Bots',\n icon: 'bots',\n name: 'bots'\n }], this.flags);\n\n this.excludePeerIds = generateList('folder-list-excluded', 'FilterExclude', [{\n icon: 'minus primary',\n text: 'ChatList.Filter.Exclude.AddChat',\n withRipple: true\n }, {\n text: 'ChatList.Filter.MutedChats',\n icon: 'mute',\n name: 'exclude_muted'\n }, {\n text: 'ChatList.Filter.Archive',\n icon: 'archive',\n name: 'exclude_archived'\n }, {\n text: 'ChatList.Filter.ReadChats',\n icon: 'readchats',\n name: 'exclude_read'\n }], this.flags);\n\n this.scrollable.append(this.stickerContainer, this.caption, inputSection.container, this.includePeerIds.container, this.excludePeerIds.container);\n\n const includedFlagsContainer = this.includePeerIds.container.querySelector('.folder-categories');\n const excludedFlagsContainer = this.excludePeerIds.container.querySelector('.folder-categories');\n\n attachClickEvent(includedFlagsContainer.querySelector('.btn') as HTMLElement, () => {\n this.slider.createTab(AppIncludedChatsTab).open(this.filter, 'included', this);\n }, {listenerSetter: this.listenerSetter});\n\n attachClickEvent(excludedFlagsContainer.querySelector('.btn') as HTMLElement, () => {\n this.slider.createTab(AppIncludedChatsTab).open(this.filter, 'excluded', this);\n }, {listenerSetter: this.listenerSetter});\n\n attachClickEvent(this.confirmBtn, () => {\n if(this.nameInputField.input.classList.contains('error')) {\n return;\n }\n\n if(!this.nameInputField.value.trim()) {\n this.nameInputField.input.classList.add('error');\n return;\n }\n\n let include = (Array.from(includedFlagsContainer.children) as HTMLElement[]).slice(1).reduce((acc, el) => acc + +!el.style.display, 0);\n include += this.filter.include_peers.length;\n\n if(!include) {\n toast('Please choose at least one chat for this folder.');\n return;\n }\n\n this.confirmBtn.setAttribute('disabled', 'true');\n\n let promise: Promise<void>;\n if(!this.filter.id) {\n promise = this.managers.filtersStorage.createDialogFilter(this.filter);\n } else {\n promise = this.managers.filtersStorage.updateDialogFilter(this.filter);\n }\n\n promise.then((bool) => {\n this.close();\n }).catch((err) => {\n if(err.type === 'DIALOG_FILTERS_TOO_MUCH') {\n toast('Sorry, you can\\'t create more folders.');\n } else {\n console.error('updateDialogFilter error:', err);\n }\n }).finally(() => {\n this.confirmBtn.removeAttribute('disabled');\n });\n }, {listenerSetter: this.listenerSetter});\n\n this.listenerSetter.add(this.nameInputField.input)('input', () => {\n this.filter.title = this.nameInputField.value;\n this.editCheckForChange();\n });\n\n const reloadMissingPromises: Promise<any>[] = this.type === 'edit' ? [\n this.managers.filtersStorage.reloadMissingPeerIds(this.filter.id, 'pinned_peers'),\n this.managers.filtersStorage.reloadMissingPeerIds(this.filter.id, 'include_peers'),\n this.managers.filtersStorage.reloadMissingPeerIds(this.filter.id, 'exclude_peers')\n ] : [];\n\n return Promise.all([\n this.loadAnimationPromise = p.animationData.then(async(cb) => {\n const player = await cb({\n container: this.stickerContainer,\n loop: false,\n autoplay: false,\n width: 86,\n height: 86\n });\n\n this.animation = player;\n\n return lottieLoader.waitForFirstFrame(player);\n }),\n\n ...reloadMissingPromises\n ]).then(() => {\n if(this.type === 'edit') {\n this.setFilter(this.originalFilter, true);\n this.onEditOpen();\n } else {\n this.setInitFilter();\n this.onCreateOpen();\n }\n });\n }\n\n onOpenAfterTimeout() {\n this.loadAnimationPromise.then(() => {\n this.animation.autoplay = true;\n this.animation.play();\n });\n }\n\n private onCreateOpen() {\n // this.caption.style.display = '';\n this.setTitle('FilterNew');\n this.menuBtn.classList.add('hide');\n this.confirmBtn.classList.remove('hide');\n\n for(const flag in this.flags) {\n // @ts-ignore\n this.flags[flag].style.display = 'none';\n }\n }\n\n private onEditOpen() {\n // this.caption.style.display = 'none';\n this.setTitle(this.type === 'create' ? 'FilterNew' : 'FilterHeaderEdit');\n\n if(this.type === 'edit') {\n this.menuBtn.classList.remove('hide');\n this.confirmBtn.classList.add('hide');\n }\n\n const filter = this.filter;\n this.nameInputField.value = wrapDraftText(filter.title);\n\n for(const flag in this.flags) {\n this.flags[flag as keyof AppEditFolderTab['flags']].style.display = !!filter.pFlags[flag as keyof AppEditFolderTab['flags']] ? '' : 'none';\n }\n\n (['includePeerIds' as const, 'excludePeerIds' as const]).forEach(async(key) => {\n const section = this[key];\n const ul = appDialogsManager.createChatList({ignoreClick: true});\n\n let peers = filter[key];\n\n // filter peers where we're kicked\n const hasPeer = async(peerId: PeerId) => {\n return !!(await this.managers.appMessagesManager.getDialogOnly(peerId)) || (peerId.isUser() ? (await this.managers.appUsersManager.getUser(peerId.toUserId()))._ === 'user' : false);\n };\n\n const filtered = await filterAsync(peers, (peerId) => hasPeer(peerId));\n peers.length = 0;\n peers.push(...filtered);\n\n peers = peers.slice();\n\n const renderMore = async(_length: number) => {\n for(let i = 0, length = Math.min(peers.length, _length); i < length; ++i) {\n const peerId = peers.shift();\n if(peerId.isUser() ? false : !(await this.managers.appMessagesManager.getDialogOnly(peerId))) {\n continue;\n }\n\n const {dom} = appDialogsManager.addDialogNew({\n peerId: peerId,\n container: ul,\n rippleEnabled: false,\n meAsSaved: true,\n avatarSize: 'small'\n });\n dom.lastMessageSpan.parentElement.remove();\n }\n\n if(peers.length) {\n showMore.lastElementChild.replaceWith(i18n('FilterShowMoreChats', [peers.length]));\n } else if(showMore) {\n showMore.remove();\n }\n };\n\n section.generateContentElement().append(ul);\n\n let showMore: HTMLElement;\n if(peers.length) {\n const content = section.generateContentElement();\n showMore = Button('folder-category-button btn btn-primary btn-transparent', {icon: 'down'});\n showMore.classList.add('load-more', 'rp-overflow');\n attachClickEvent(showMore, () => renderMore(20), {listenerSetter: this.listenerSetter});\n showMore.append(i18n('FilterShowMoreChats', [peers.length]));\n\n content.append(showMore);\n }\n\n renderMore(4);\n });\n }\n\n editCheckForChange() {\n if(this.type === 'edit') {\n const changed = !deepEqual(this.originalFilter, this.filter);\n this.confirmBtn.classList.toggle('hide', !changed);\n this.menuBtn.classList.toggle('hide', changed);\n }\n };\n\n setFilter(filter: DialogFilter, firstTime: boolean) {\n if(this.container) {\n // cleanup\n Array.from(this.container.querySelectorAll('ul, .load-more')).forEach((el) => el.remove());\n }\n\n if(firstTime) {\n this.originalFilter = filter;\n this.filter = copy(filter);\n } else {\n this.filter = filter;\n this.onEditOpen();\n this.editCheckForChange();\n }\n }\n\n public setInitFilter(filter?: DialogFilter) {\n if(filter === undefined) {\n this.setFilter({\n _: 'dialogFilter',\n id: 0,\n title: '',\n pFlags: {},\n pinned_peers: [],\n include_peers: [],\n exclude_peers: [],\n pinnedPeerIds: [],\n includePeerIds: [],\n excludePeerIds: []\n }, true);\n this.type = 'create';\n } else {\n this.setFilter(filter, true);\n this.type = 'edit';\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport InputField from '../../inputField';\nimport {SliderSuperTab} from '../../slider';\nimport EditPeer from '../../editPeer';\nimport {UsernameInputField} from '../../usernameInputField';\nimport {i18n, i18n_, LangPackKey} from '../../../lib/langPack';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport rootScope from '../../../lib/rootScope';\nimport setBlankToAnchor from '../../../lib/richTextProcessor/setBlankToAnchor';\nimport getPeerEditableUsername from '../../../lib/appManagers/utils/peers/getPeerEditableUsername';\nimport SettingSection, {generateSection} from '../../settingSection';\nimport UsernamesSection from '../../usernamesSection';\n\n// TODO: аватарка не поменяется в этой вкладке после изменения почему-то (если поставить в другом клиенте, и потом тут проверить, для этого ещё вышел в чатлист)\n\nexport function purchaseUsernameCaption() {\n const p = document.createElement('div');\n const FRAGMENT_USERNAME_URL = 'https://fragment.com/username/';\n const a = setBlankToAnchor(document.createElement('a'));\n const purchaseText = i18n('Username.Purchase', [a]);\n purchaseText.classList.add('username-purchase-help');\n p.append(\n purchaseText,\n document.createElement('br'),\n document.createElement('br')\n );\n p.classList.add('hide');\n\n return {\n element: p,\n setUsername: (username: string) => {\n if(username) {\n a.href = FRAGMENT_USERNAME_URL + username;\n }\n\n p.classList.toggle('hide', !username);\n }\n };\n}\n\nexport default class AppEditProfileTab extends SliderSuperTab {\n private firstNameInputField: InputField;\n private lastNameInputField: InputField;\n private bioInputField: InputField;\n private usernameInputField: UsernameInputField;\n\n private profileUrlContainer: HTMLDivElement;\n private profileUrlAnchor: HTMLAnchorElement;\n\n private editPeer: EditPeer;\n\n public static getInitArgs() {\n return {\n bioMaxLength: rootScope.managers.apiManager.getLimit('bio'),\n user: rootScope.managers.appUsersManager.getSelf(),\n userFull: rootScope.managers.appProfileManager.getProfile(rootScope.myId.toUserId())\n };\n }\n\n public async init(p: ReturnType<typeof AppEditProfileTab['getInitArgs']>) {\n this.container.classList.add('edit-profile-container');\n this.setTitle('EditAccount.Title');\n\n const inputFields: InputField[] = [];\n\n const [bioMaxLength, user, userFull] = await Promise.all([p.bioMaxLength, p.user, p.userFull]);\n\n {\n const section = generateSection(this.scrollable, undefined, 'Bio.Description');\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n this.firstNameInputField = new InputField({\n label: 'EditProfile.FirstNameLabel',\n name: 'first-name',\n maxLength: 70\n });\n this.lastNameInputField = new InputField({\n label: 'Login.Register.LastName.Placeholder',\n name: 'last-name',\n maxLength: 64\n });\n this.bioInputField = new InputField({\n label: 'EditProfile.BioLabel',\n name: 'bio',\n maxLength: bioMaxLength\n });\n\n inputWrapper.append(this.firstNameInputField.container, this.lastNameInputField.container, this.bioInputField.container);\n\n const caption = document.createElement('div');\n caption.classList.add('caption');\n i18n_({element: caption, key: 'Bio.Description'});\n\n inputFields.push(this.firstNameInputField, this.lastNameInputField, this.bioInputField);\n\n this.editPeer = new EditPeer({\n peerId: rootScope.myId,\n inputFields,\n listenerSetter: this.listenerSetter\n });\n\n this.content.append(this.editPeer.nextBtn);\n\n section.append(this.editPeer.avatarEdit.container, inputWrapper);\n }\n\n {\n const section = new SettingSection({\n name: 'EditAccount.Username',\n caption: true\n });\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n this.usernameInputField = new UsernameInputField({\n label: 'EditProfile.Username.Label',\n name: 'username',\n plainText: true,\n listenerSetter: this.listenerSetter,\n onChange: () => {\n this.editPeer.handleChange();\n // this.setProfileUrl();\n\n const {error} = this.usernameInputField;\n const isPurchase = error?.type === 'USERNAME_PURCHASE_AVAILABLE';\n setUsername(isPurchase ? this.usernameInputField.value : undefined);\n },\n availableText: 'EditProfile.Username.Available',\n takenText: 'EditProfile.Username.Taken',\n invalidText: 'EditProfile.Username.Invalid'\n }, this.managers);\n\n inputWrapper.append(this.usernameInputField.container);\n\n const caption = section.caption;\n\n const {setUsername, element: p} = purchaseUsernameCaption();\n\n caption.append(\n p,\n i18n('UsernameHelp')\n // document.createElement('br'),\n // document.createElement('br')\n );\n\n // const profileUrlContainer = this.profileUrlContainer = document.createElement('div');\n // profileUrlContainer.classList.add('profile-url-container');\n // const profileUrlAnchor = this.profileUrlAnchor = anchorCopy();\n // profileUrlContainer.append(i18n('UsernameHelpLink', [profileUrlAnchor]));\n // caption.append(profileUrlContainer);\n\n inputFields.push(this.usernameInputField);\n section.content.append(inputWrapper);\n this.scrollable.append(section.container);\n }\n\n {\n const section = new UsernamesSection({\n peerId: rootScope.myId,\n peer: user,\n listenerSetter: this.listenerSetter,\n usernameInputField: this.usernameInputField,\n middleware: this.middlewareHelper.get()\n });\n\n this.scrollable.append(section.container);\n }\n\n attachClickEvent(this.editPeer.nextBtn, () => {\n this.editPeer.nextBtn.disabled = true;\n\n const promises: Promise<any>[] = [];\n\n const profilePromise = this.managers.appProfileManager.updateProfile(\n this.firstNameInputField.value,\n this.lastNameInputField.value,\n this.bioInputField.value\n );\n promises.push(profilePromise.then(() => {\n this.close();\n }, (err) => {\n console.error('updateProfile error:', err);\n }));\n\n if(this.editPeer.uploadAvatar) {\n promises.push(this.editPeer.uploadAvatar().then((inputFile) => {\n return this.managers.appProfileManager.uploadProfilePhoto(inputFile);\n }));\n }\n\n if(this.usernameInputField.isValidToChange()) {\n promises.push(this.managers.appUsersManager.updateUsername(this.usernameInputField.value));\n }\n\n Promise.race(promises).finally(() => {\n this.editPeer.nextBtn.removeAttribute('disabled');\n });\n }, {listenerSetter: this.listenerSetter});\n\n this.firstNameInputField.setOriginalValue(user.first_name, true);\n this.lastNameInputField.setOriginalValue(user.last_name, true);\n this.bioInputField.setOriginalValue(userFull.about, true);\n this.usernameInputField.setOriginalValue(getPeerEditableUsername(user), true);\n\n // this.setProfileUrl();\n this.editPeer.handleChange();\n }\n\n // private setProfileUrl() {\n // if(this.usernameInputField.input.classList.contains('error') || !this.usernameInputField.value.length) {\n // this.profileUrlContainer.style.display = 'none';\n // } else {\n // this.profileUrlContainer.style.display = '';\n // this.profileUrlAnchor.replaceWith(this.profileUrlAnchor = anchorCopy({mePath: this.usernameInputField.value}));\n // }\n // }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport appImManager, {APP_TABS} from '../../lib/appManagers/appImManager';\nimport SidebarSlider from '../slider';\nimport mediaSizes, {ScreenSize} from '../../helpers/mediaSizes';\nimport AppSharedMediaTab from './tabs/sharedMedia';\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport {AppManagers} from '../../lib/appManagers/managers';\n\nexport const RIGHT_COLUMN_ACTIVE_CLASSNAME = 'is-right-column-shown';\n\nexport class AppSidebarRight extends SidebarSlider {\n private isColumnProportionSet = false;\n private sharedMediaTab: AppSharedMediaTab;\n // public rect: DOMRect;\n\n constructor() {\n super({\n sidebarEl: document.getElementById('column-right') as HTMLElement,\n canHideFirst: true,\n navigationType: 'right'\n });\n }\n\n construct(managers: AppManagers) {\n this.managers = managers;\n\n mediaSizes.addEventListener('changeScreen', (from, to) => {\n if(to === ScreenSize.medium && from !== ScreenSize.mobile) {\n this.toggleSidebar(false);\n }\n });\n\n mediaSizes.addEventListener('resize', () => {\n this.setColumnProportion();\n });\n }\n\n public createSharedMediaTab() {\n const tab = this.createTab(AppSharedMediaTab, false, true);\n tab.slider = this;\n // this.tabsContainer.prepend(tab.container);\n return tab;\n }\n\n public replaceSharedMediaTab(tab?: AppSharedMediaTab) {\n const previousTab = this.sharedMediaTab;\n if(previousTab) {\n const idx = this.historyTabIds.indexOf(previousTab);\n\n if(this._selectTab.getFrom() === previousTab.container) {\n this._selectTab.setFrom(tab?.container);\n }\n\n if(tab) {\n if(idx !== -1) {\n this.historyTabIds[idx] = tab;\n }\n\n const wasActive = previousTab.container.classList.contains('active');\n if(wasActive) {\n tab.container.classList.add('active');\n }\n\n previousTab.container.replaceWith(tab.container);\n } else {\n if(idx !== -1) {\n this.historyTabIds.splice(idx, 1);\n }\n\n previousTab.container.remove();\n }\n } else {\n this.tabsContainer.prepend(tab.container);\n }\n\n this.sharedMediaTab = tab;\n }\n\n public onCloseTab(id: number, animate: boolean, isNavigation?: boolean) {\n if(!this.historyTabIds.length) {\n this.toggleSidebar(false, animate);\n }\n\n super.onCloseTab(id, animate, isNavigation);\n }\n\n private setColumnProportion() {\n const proportion = this.sidebarEl.scrollWidth / this.sidebarEl.previousElementSibling.scrollWidth;\n document.documentElement.style.setProperty('--right-column-proportion', '' + proportion);\n // this.rect = this.sidebarEl.getBoundingClientRect();\n }\n\n public toggleSidebar(enable?: boolean, animate?: boolean) {\n const active = document.body.classList.contains(RIGHT_COLUMN_ACTIVE_CLASSNAME);\n let willChange: boolean;\n if(enable !== undefined) {\n if(enable) {\n if(!active) {\n willChange = true;\n }\n } else if(active) {\n willChange = true;\n }\n } else {\n willChange = true;\n }\n\n if(!willChange) return Promise.resolve();\n\n if(!active && !this.historyTabIds.length) {\n this.sharedMediaTab.open();\n }\n\n if(!this.isColumnProportionSet) {\n this.setColumnProportion();\n this.isColumnProportionSet = true;\n }\n\n const animationPromise = appImManager.selectTab(active ? APP_TABS.CHAT : APP_TABS.PROFILE, animate);\n document.body.classList.toggle(RIGHT_COLUMN_ACTIVE_CLASSNAME, enable);\n return animationPromise;\n\n /* return new Promise((resolve, reject) => {\n const hidden: {element: HTMLDivElement, height: number}[] = [];\n const observer = new IntersectionObserver((entries) => {\n for(const entry of entries) {\n const bubble = entry.target as HTMLDivElement;\n if(!entry.isIntersecting) {\n hidden.push({element: bubble, height: bubble.scrollHeight});\n }\n }\n\n for(const item of hidden) {\n item.element.style.minHeight = item.height + 'px';\n (item.element.firstElementChild as HTMLElement).style.display = 'none';\n item.element.style.width = '1px';\n }\n\n //console.log('hidden', hidden);\n observer.disconnect();\n\n set();\n\n setTimeout(() => {\n for(const item of hidden) {\n item.element.style.minHeight = '';\n item.element.style.width = '';\n (item.element.firstElementChild as HTMLElement).style.display = '';\n }\n\n resolve();\n }, 200);\n });\n\n const length = Object.keys(appImManager.bubbles).length;\n if(length) {\n for(const i in appImManager.bubbles) {\n observer.observe(appImManager.bubbles[i]);\n }\n } else {\n set();\n setTimeout(resolve, 200);\n }\n }); */\n }\n}\n\nconst appSidebarRight = new AppSidebarRight();\nMOUNT_CLASS_TO.appSidebarRight = appSidebarRight;\nexport default appSidebarRight;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTab} from '../../slider'\nimport InputField from '../../inputField';\nimport EditPeer from '../../editPeer';\nimport Row, {CreateRowFromCheckboxField} from '../../row';\nimport CheckboxField from '../../checkboxField';\nimport Button from '../../button';\nimport PeerTitle from '../../peerTitle';\nimport rootScope from '../../../lib/rootScope';\nimport PopupPeer from '../../popups/peer';\nimport PopupElement, {addCancelButton} from '../../popups';\nimport {i18n} from '../../../lib/langPack';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport toggleDisability from '../../../helpers/dom/toggleDisability';\nimport getPeerId from '../../../lib/appManagers/utils/peers/getPeerId';\nimport formatUserPhone from '../../wrappers/formatUserPhone';\nimport SettingSection from '../../settingSection';\nimport wrapPeerTitle from '../../wrappers/peerTitle';\n\nexport default class AppEditContactTab extends SliderSuperTab {\n private nameInputField: InputField;\n private lastNameInputField: InputField;\n private editPeer: EditPeer;\n private sharePhoneCheckboxField: CheckboxField;\n public peerId: PeerId;\n\n public async init() {\n const {peerId} = this;\n const userId = peerId.toUserId();\n this.container.classList.add('edit-peer-container', 'edit-contact-container');\n const [isContact, privacy] = await Promise.all([\n this.managers.appUsersManager.isContact(userId),\n this.managers.appPrivacyManager.getPrivacy('inputPrivacyKeyPhoneNumber')\n ]);\n const isNew = !isContact;\n this.setTitle(isNew ? 'AddContactTitle' : 'Edit');\n\n {\n const section = new SettingSection({noDelimiter: true});\n const inputFields: InputField[] = [];\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n this.nameInputField = new InputField({\n label: 'FirstName',\n name: 'contact-name',\n maxLength: 70,\n required: true\n });\n this.lastNameInputField = new InputField({\n label: 'LastName',\n name: 'contact-lastname',\n maxLength: 70\n });\n\n if(userId) {\n const user = await this.managers.appUsersManager.getUser(userId);\n\n if(isNew) {\n this.nameInputField.setDraftValue(user.first_name);\n this.lastNameInputField.setDraftValue(user.last_name);\n } else {\n this.nameInputField.setOriginalValue(user.first_name);\n this.lastNameInputField.setOriginalValue(user.last_name);\n }\n }\n\n inputWrapper.append(this.nameInputField.container, this.lastNameInputField.container);\n inputFields.push(this.nameInputField, this.lastNameInputField);\n\n this.editPeer = new EditPeer({\n peerId: peerId,\n inputFields,\n listenerSetter: this.listenerSetter,\n doNotEditAvatar: true\n });\n this.content.append(this.editPeer.nextBtn);\n\n if(peerId) {\n const div = document.createElement('div');\n div.classList.add('avatar-edit');\n div.append(this.editPeer.avatarElem);\n\n const notificationsCheckboxField = new CheckboxField({\n text: 'Notifications'\n });\n\n notificationsCheckboxField.input.addEventListener('change', (e) => {\n if(!e.isTrusted) {\n return;\n }\n\n this.managers.appMessagesManager.togglePeerMute({peerId});\n });\n\n this.listenerSetter.add(rootScope)('notify_settings', async(update) => {\n if(update.peer._ !== 'notifyPeer') return;\n const peerId = getPeerId(update.peer.peer);\n if(peerId === peerId) {\n const enabled = !(await this.managers.appNotificationsManager.isMuted(update.notify_settings));\n if(enabled !== notificationsCheckboxField.checked) {\n notificationsCheckboxField.checked = enabled;\n }\n }\n });\n\n const profileNameDiv = document.createElement('div');\n profileNameDiv.classList.add('profile-name');\n profileNameDiv.append(new PeerTitle({\n peerId\n }).element);\n\n const profileSubtitleDiv = document.createElement('div');\n profileSubtitleDiv.classList.add('profile-subtitle');\n profileSubtitleDiv.append(i18n('EditContact.OriginalName'));\n\n section.content.append(div, profileNameDiv, profileSubtitleDiv, inputWrapper);\n\n if(!isNew) {\n const notificationsRow = new Row({\n checkboxField: notificationsCheckboxField,\n withCheckboxSubtitle: true,\n listenerSetter: this.listenerSetter\n });\n\n const enabled = !(await this.managers.appNotificationsManager.isPeerLocalMuted({peerId, respectType: false}));\n notificationsCheckboxField.checked = enabled;\n\n section.content.append(notificationsRow.container);\n } else {\n const user = await this.managers.appUsersManager.getUser(userId);\n\n const phoneRow = new Row({\n icon: 'phone',\n titleLangKey: user.phone ? undefined : 'MobileHidden',\n title: user.phone ? formatUserPhone(user.phone) : undefined,\n subtitleLangKey: user.phone ? 'Phone' : 'MobileHiddenExceptionInfo',\n subtitleLangArgs: user.phone ? undefined : [new PeerTitle({peerId: peerId}).element]\n });\n\n section.content.append(phoneRow.container);\n }\n } else {\n section.content.append(inputWrapper);\n }\n\n this.scrollable.append(section.container);\n }\n\n if(!isNew) {\n const section = new SettingSection();\n\n const btnDelete = Button('btn-primary btn-transparent danger', {icon: 'delete', text: 'PeerInfo.DeleteContact'});\n\n attachClickEvent(btnDelete, () => {\n PopupElement.createPopup(PopupPeer, 'popup-delete-contact', {\n peerId: peerId,\n titleLangKey: 'DeleteContact',\n descriptionLangKey: 'AreYouSureDeleteContact',\n buttons: addCancelButton([{\n langKey: 'Delete',\n callback: () => {\n const toggle = toggleDisability([btnDelete], true);\n\n this.managers.appUsersManager.deleteContacts([userId]).then(() => {\n this.close();\n }, () => {\n toggle();\n });\n },\n isDanger: true\n }])\n }).show();\n }, {listenerSetter: this.listenerSetter});\n\n section.content.append(btnDelete);\n\n this.scrollable.append(section.container);\n } else if(\n privacy.some((privacyRule) => privacyRule._ === 'privacyValueDisallowAll') &&\n !privacy.some((privacyRule) => privacyRule._ === 'privacyValueAllowUsers' && privacyRule.users.includes(userId))\n ) {\n const section = new SettingSection({\n caption: 'NewContact.Exception.ShareMyPhoneNumber.Desc',\n captionArgs: [await wrapPeerTitle({peerId: this.peerId})]\n });\n const checkboxField = this.sharePhoneCheckboxField = new CheckboxField({\n text: 'NewContact.Exception.ShareMyPhoneNumber',\n checked: true\n });\n const row = CreateRowFromCheckboxField(checkboxField);\n\n section.content.append(row.container);\n\n this.scrollable.append(section.container);\n }\n\n attachClickEvent(this.editPeer.nextBtn, async() => {\n this.editPeer.nextBtn.disabled = true;\n\n this.managers.appUsersManager.addContact(\n userId,\n this.nameInputField.value,\n this.lastNameInputField.value,\n (await this.managers.appUsersManager.getUser(userId)).phone,\n this.sharePhoneCheckboxField?.checked\n ).finally(() => {\n this.editPeer.nextBtn.removeAttribute('disabled');\n this.close();\n });\n }, {listenerSetter: this.listenerSetter});\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport toggleDisability from '../../../helpers/dom/toggleDisability';\nimport {makeMediaSize} from '../../../helpers/mediaSize';\nimport copy from '../../../helpers/object/copy';\nimport deepEqual from '../../../helpers/object/deepEqual';\nimport {ForumTopic} from '../../../layer';\nimport appImManager from '../../../lib/appManagers/appImManager';\nimport {GENERAL_TOPIC_ID, TOPIC_COLORS} from '../../../lib/mtproto/mtproto_config';\nimport getAbbreviation from '../../../lib/richTextProcessor/getAbbreviation';\nimport ButtonIcon from '../../buttonIcon';\nimport CheckboxField from '../../checkboxField';\nimport EmojiTab from '../../emoticonsDropdown/tabs/emoji';\nimport InputField from '../../inputField';\nimport Row from '../../row';\nimport SettingSection from '../../settingSection';\nimport appSidebarLeft from '../../sidebarLeft';\nimport SliderSuperTab from '../../sliderTab';\nimport {wrapTopicIcon} from '../../wrappers/messageActionTextNewUnsafe';\n\nconst size = 64;\nconst mediaSize = makeMediaSize(size, size);\n\nexport default class AppEditTopicTab extends SliderSuperTab {\n private iconDiv: HTMLElement;\n private colorIndex: number;\n private nameInputField: InputField;\n private topic: Parameters<typeof wrapTopicIcon>[0]['topic'];\n private emojiElement: HTMLElement;\n private confirmBtn: HTMLButtonElement;\n private originalTopic: ForumTopic.forumTopic;\n\n public async init(peerId: PeerId, threadId?: number) {\n this.colorIndex = 0;\n const isNew = !threadId;\n const isGeneral = threadId === GENERAL_TOPIC_ID;\n this.container.classList.add('edit-topic-container');\n this.setTitle(isNew ? 'NewTopic' : 'ForumTopic.Title.Edit');\n const chatId = peerId.toChatId();\n\n if(threadId) {\n this.topic = this.originalTopic = copy(await this.managers.dialogsStorage.getForumTopic(peerId, threadId));\n }\n\n {\n const section = new SettingSection({\n name: isGeneral ? 'CreateGeneralTopicTitle' : 'CreateTopicTitle'\n });\n\n const iconDiv = this.iconDiv = document.createElement('div');\n iconDiv.classList.add('edit-topic-icon-container');\n\n !threadId && attachClickEvent(iconDiv, () => {\n if(this.topic.icon_emoji_id) {\n return;\n }\n\n this.colorIndex = (this.colorIndex + 1) % TOPIC_COLORS.length;\n this.setIcon();\n }, {listenerSetter: this.listenerSetter});\n\n if(threadId) {\n iconDiv.classList.add('disable-hover');\n }\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n const nameInputField = this.nameInputField = new InputField({\n label: 'ForumTopic.Name.Placeholder',\n withLinebreaks: false,\n name: 'topic-name',\n maxLength: 70,\n required: true\n });\n\n if(this.topic) {\n nameInputField.setOriginalValue(this.topic.title, true);\n }\n\n const confirmBtn = this.confirmBtn = ButtonIcon('check btn-confirm blue hide', {noRipple: true});\n this.header.append(confirmBtn);\n\n attachClickEvent(confirmBtn, () => {\n const toggle = toggleDisability([confirmBtn], true);\n if(threadId) {\n this.managers.appChatsManager.editForumTopic({\n chatId,\n topicId: threadId,\n title: nameInputField.value,\n iconEmojiId: this.topic.icon_emoji_id || 0\n }).then(() => {\n this.close();\n }).catch((err) => {\n console.error('edit topic error', err);\n toggle();\n });\n } else {\n this.managers.appChatsManager.createForumTopic({\n chatId,\n iconColor: TOPIC_COLORS[this.colorIndex],\n iconEmojiId: this.topic.icon_emoji_id,\n title: nameInputField.value\n }).then((threadId) => {\n this.close();\n appImManager.setInnerPeer({\n peerId,\n threadId\n });\n }).catch((err) => {\n console.error('create topic error', err);\n toggle();\n });\n }\n }, {listenerSetter: this.listenerSetter});\n\n this.listenerSetter.add(nameInputField.input)('input', () => {\n this.validate();\n this.setIcon(this.topic?.icon_emoji_id);\n });\n\n inputWrapper.append(nameInputField.container);\n\n section.content.append(iconDiv, inputWrapper);\n\n this.scrollable.append(section.container);\n }\n\n const promises: Promise<any>[] = [];\n\n if(!isGeneral) {\n const section = new SettingSection({});\n section.container.classList.add('edit-topic-emoticons-container');\n const emojiTab = new EmojiTab({\n managers: this.managers,\n isStandalone: true,\n noRegularEmoji: true,\n stickerSetId: 'inputStickerSetEmojiDefaultTopicIcons',\n onClick: (emoji) => {\n emojiTab.setActive(!emoji.docId ? {emoji: undefined, docId: undefined} : emoji);\n this.setIcon(emoji.docId);\n }\n });\n emojiTab.getContainerSize = () => ({\n width: appSidebarLeft.rect.width,\n height: 400\n });\n\n this.middlewareHelper.onDestroy(() => {\n emojiTab.destroy();\n });\n\n emojiTab.container.classList.remove('tabs-tab');\n\n this.emojiElement = document.createElement('span');\n this.emojiElement.classList.add('super-emoji-topic-icon');\n\n const promise = emojiTab.init().then(async() => {\n const category = emojiTab.getCustomCategory();\n\n const iconEmojiId = this.topic?.icon_emoji_id;\n emojiTab.addEmojiToCategory({\n category,\n element: this.emojiElement,\n batch: false,\n prepend: true,\n active: !iconEmojiId\n });\n\n if(iconEmojiId) {\n emojiTab.setActive({docId: iconEmojiId, emoji: ''});\n }\n });\n\n promises.push(promise);\n\n section.content.replaceWith(emojiTab.container);\n this.scrollable.append(section.container);\n } else {\n const section = new SettingSection({caption: 'EditTopicHideInfo'});\n\n const checkboxField = new CheckboxField({\n // toggle: true,\n checked: !(this.topic as ForumTopic.forumTopic).pFlags.hidden,\n text: 'EditTopicHide'\n });\n\n this.listenerSetter.add(checkboxField.input)('change', () => {\n const promise = this.managers.appChatsManager.editForumTopic({\n chatId,\n topicId: threadId,\n hidden: !checkboxField.checked\n });\n\n row.disableWithPromise(promise);\n });\n\n const row = new Row({\n checkboxField\n });\n\n section.content.append(row.container);\n\n this.scrollable.append(section.container);\n }\n\n return Promise.all(promises).then(() => {\n return this.s();\n });\n }\n\n private validate() {\n let isChanged = this.nameInputField.isValidToChange();\n if(!isChanged && this.originalTopic) {\n isChanged = this.topic.icon_emoji_id !== this.originalTopic.icon_emoji_id;\n }\n\n this.confirmBtn.classList.toggle('hide', !isChanged);\n }\n\n private s() {\n if(this.topic?.icon_color) {\n this.colorIndex = TOPIC_COLORS.indexOf(this.topic.icon_color);\n }\n\n return this.setIcon(this.topic?.icon_emoji_id, undefined, true);\n }\n\n private async setIcon(iconEmojiId?: Long, appendTo = this.iconDiv, force?: boolean) {\n const title = this.nameInputField.value;\n\n const isMainIcon = appendTo === this.iconDiv;\n\n if(isMainIcon) {\n const newTopic: AppEditTopicTab['topic'] = {\n id: this.topic?.id,\n icon_color: TOPIC_COLORS[this.colorIndex],\n title: getAbbreviation(title, true).text || 'A',\n icon_emoji_id: iconEmojiId\n };\n\n const oldTopic = this.topic;\n this.topic = newTopic;\n\n if(\n force ||\n !oldTopic ||\n oldTopic.icon_color !== newTopic.icon_color ||\n oldTopic.title !== newTopic.title\n ) {\n this.setIcon(undefined, this.emojiElement);\n }\n\n if(deepEqual(oldTopic, newTopic) && !force) {\n return;\n }\n\n this.validate();\n }\n\n const el = await wrapTopicIcon({\n topic: isMainIcon ? this.topic : {...this.topic, icon_emoji_id: undefined},\n customEmojiSize: mediaSize,\n middleware: this.middlewareHelper.get()\n });\n\n const span = document.createElement('div');\n span.classList.add('edit-topic-icon');\n span.append(el);\n\n const oldEl = appendTo.lastElementChild as HTMLElement;\n appendTo.append(span);\n\n const applyFadeAnimation = (el: HTMLElement, fadeIn: boolean) => {\n const frames: Keyframe[] = [\n {opacity: '0', transform: 'scale(0.8)'},\n {opacity: '1', transform: 'scale(1)'}\n ];\n\n const animation = el.animate(frames, {\n duration: 200,\n iterations: 1,\n easing: 'ease-in-out',\n fill: 'forwards',\n direction: fadeIn ? 'normal' : 'reverse'\n });\n\n return new Promise<void>((resolve) => {\n animation.addEventListener('finish', () => {\n resolve();\n }, {once: true});\n });\n };\n\n if(oldEl) {\n applyFadeAnimation(oldEl, false).then(() => oldEl.remove());\n }\n\n applyFadeAnimation(span, true);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {copyTextToClipboard} from '../../../helpers/clipboard';\nimport {randomLong} from '../../../helpers/random';\nimport {Chat, ChatFull, ExportedChatInvite} from '../../../layer';\nimport Button from '../../button';\nimport {setButtonLoader} from '../../putPreloader';\nimport RadioField from '../../radioField';\nimport Row, {RadioFormFromRows} from '../../row';\nimport {toast} from '../../toast';\nimport {UsernameInputField} from '../../usernameInputField';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport I18n, {i18n} from '../../../lib/langPack';\nimport PopupPeer from '../../popups/peer';\nimport ButtonCorner from '../../buttonCorner';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport toggleDisability from '../../../helpers/dom/toggleDisability';\nimport CheckboxField from '../../checkboxField';\nimport rootScope from '../../../lib/rootScope';\nimport SettingSection from '../../settingSection';\nimport UsernamesSection from '../../usernamesSection';\nimport getPeerEditableUsername from '../../../lib/appManagers/utils/peers/getPeerEditableUsername';\nimport getPeerActiveUsernames from '../../../lib/appManagers/utils/peers/getPeerActiveUsernames';\nimport {purchaseUsernameCaption} from '../../sidebarLeft/tabs/editProfile';\nimport confirmationPopup from '../../confirmationPopup';\nimport PopupElement from '../../popups';\n\nexport default class AppChatTypeTab extends SliderSuperTabEventable {\n public chatId: ChatId;\n public chatFull: ChatFull;\n\n public async init() {\n this.container.classList.add('edit-peer-container', 'group-type-container');\n\n const isBroadcast = await this.managers.appChatsManager.isBroadcast(this.chatId);\n\n this.setTitle(isBroadcast ? 'ChannelType' : 'GroupType');\n\n const section = new SettingSection({\n name: isBroadcast ? 'ChannelType' : 'GroupType'\n });\n\n const random = randomLong();\n const privateRow = new Row({\n radioField: new RadioField({\n langKey: isBroadcast ? 'ChannelPrivate' : 'MegaPrivate',\n name: random,\n value: 'private'\n }),\n subtitleLangKey: isBroadcast ? 'ChannelPrivateInfo' : 'MegaPrivateInfo'\n });\n const publicRow = new Row({\n radioField: new RadioField({\n langKey: isBroadcast ? 'ChannelPublic' : 'MegaPublic',\n name: random,\n value: 'public'\n }),\n subtitleLangKey: isBroadcast ? 'ChannelPublicInfo' : 'MegaPublicInfo'\n });\n const form = RadioFormFromRows([privateRow, publicRow], (value) => {\n const a: HTMLElement[][] = [[privateSection.container], [publicContainer]];\n if(value === 'public') a.reverse();\n\n a[0].forEach((container) => container.classList.remove('hide'));\n a[1].forEach((container) => container.classList.add('hide'));\n\n onChange();\n });\n\n let chat: Chat = await this.managers.appChatsManager.getChat(this.chatId);\n\n const chatUpdateListeners: {[type in 'basic']: (() => void)[]} = {basic: []};\n const addChatUpdateListener = (callback: () => void, type: 'basic' = 'basic') => {\n chatUpdateListeners[type].push(callback);\n };\n\n this.listenerSetter.add(rootScope)('chat_update', async(chatId) => {\n if(this.chatId === chatId) {\n chat = await this.managers.appChatsManager.getChat(this.chatId) as typeof chat;\n chatUpdateListeners['basic'].forEach((callback) => callback());\n }\n });\n\n section.content.append(form);\n\n const privateSection = new SettingSection({});\n\n // let revoked = false;\n const linkRow = new Row({\n title: (this.chatFull.exported_invite as ExportedChatInvite.chatInviteExported).link,\n subtitleLangKey: isBroadcast ? 'ChannelPrivateLinkHelp' : 'MegaPrivateLinkHelp',\n clickable: () => {\n copyTextToClipboard((this.chatFull.exported_invite as ExportedChatInvite.chatInviteExported).link);\n toast(I18n.format('LinkCopied', true));\n },\n listenerSetter: this.listenerSetter\n });\n\n const btnRevoke = Button('btn-primary btn-transparent danger', {icon: 'delete', text: 'RevokeLink'});\n\n attachClickEvent(btnRevoke, () => {\n PopupElement.createPopup(PopupPeer, 'revoke-link', {\n buttons: [{\n langKey: 'RevokeButton',\n callback: () => {\n const toggle = toggleDisability([btnRevoke], true);\n\n this.managers.appProfileManager.getChatInviteLink(this.chatId, true).then((link) => {\n toggle();\n linkRow.title.textContent = link;\n // revoked = true;\n // onChange();\n });\n }\n }],\n titleLangKey: 'RevokeLink',\n descriptionLangKey: 'RevokeAlert'\n }).show();\n }, {listenerSetter: this.listenerSetter});\n\n privateSection.content.append(linkRow.container, btnRevoke);\n\n const publicSection = new SettingSection({\n caption: true,\n noDelimiter: true\n });\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n const placeholder = 't.me/';\n\n const onChange = () => {\n const changed = (privateRow.radioField.checked && (originalValue !== placeholder/* || revoked */)) ||\n (linkInputField.isValidToChange() && linkInputField.input.classList.contains('valid'));\n applyBtn.classList.toggle('is-visible', changed);\n\n const {error} = linkInputField;\n const isPurchase = error?.type === 'USERNAME_PURCHASE_AVAILABLE';\n setUsername(isPurchase ? linkInputField.getValue() : undefined);\n };\n\n const linkInputField = new UsernameInputField({\n label: 'SetUrlPlaceholder',\n name: 'group-public-link',\n plainText: true,\n listenerSetter: this.listenerSetter,\n availableText: 'Link.Available',\n invalidText: 'Link.Invalid',\n takenText: 'Link.Taken',\n onChange: onChange,\n peerId: this.chatId.toPeerId(true),\n head: placeholder\n }, this.managers);\n\n const {setUsername, element: p} = purchaseUsernameCaption();\n\n publicSection.caption.append(\n p,\n i18n(isBroadcast ? 'Channel.UsernameAboutChannel' : 'Channel.UsernameAboutGroup')\n );\n\n const usernamesSection = new UsernamesSection({\n peerId: this.chatId.toPeerId(true),\n peer: chat as Chat.channel,\n listenerSetter: this.listenerSetter,\n usernameInputField: linkInputField,\n middleware: this.middlewareHelper.get()\n });\n\n const publicContainer = document.createElement('div');\n publicContainer.append(publicSection.container, usernamesSection.container);\n\n const originalValue = placeholder + (getPeerEditableUsername(chat as Chat.channel) || '');\n\n inputWrapper.append(linkInputField.container)\n publicSection.content.append(inputWrapper);\n\n const applyBtn = ButtonCorner({icon: 'check', className: 'is-visible'});\n this.content.append(applyBtn);\n\n attachClickEvent(applyBtn, async() => {\n const username = publicRow.radioField.checked ? linkInputField.getValue() : '';\n if(!username) {\n const chat = await this.managers.appChatsManager.getChat(this.chatId);\n const wasUsername = getPeerEditableUsername(chat as Chat.channel);\n if(wasUsername) {\n await confirmationPopup({\n descriptionLangKey: isBroadcast ? 'ChannelVisibility.Confirm.MakePrivate.Channel' : 'ChannelVisibility.Confirm.MakePrivate.Group',\n descriptionLangArgs: [wasUsername],\n button: {\n langKey: 'OK'\n }\n });\n }\n }\n\n /* const unsetLoader = */setButtonLoader(applyBtn);\n this.managers.appChatsManager.migrateChat(this.chatId).then((channelId) => {\n if(!username) {\n return this.managers.appChatsManager.makeChannelPrivate(channelId);\n } else {\n return this.managers.appChatsManager.updateUsername(channelId, username);\n }\n }).then(() => {\n // unsetLoader();\n this.close();\n });\n }, {listenerSetter: this.listenerSetter});\n\n (originalValue !== placeholder || getPeerActiveUsernames(chat as Chat.channel).length ? publicRow : privateRow).radioField.checked = true;\n linkInputField.setOriginalValue(originalValue, true);\n\n this.scrollable.append(section.container, privateSection.container, publicContainer);\n\n {\n const section = new SettingSection({\n name: 'SavingContentTitle',\n caption: isBroadcast ? 'RestrictSavingContentInfoChannel' : 'RestrictSavingContentInfoGroup'\n });\n\n const checkboxField = new CheckboxField({\n text: 'RestrictSavingContent',\n withRipple: true\n });\n\n this.listenerSetter.add(checkboxField.input)('change', () => {\n const toggle = checkboxField.toggleDisability(true);\n this.managers.appChatsManager.toggleNoForwards(this.chatId, checkboxField.checked).then(() => {\n toggle();\n });\n });\n\n const onChatUpdate = () => {\n checkboxField.setValueSilently(!!(chat as Chat.channel).pFlags.noforwards);\n };\n\n addChatUpdateListener(onChatUpdate);\n\n onChatUpdate();\n\n section.content.append(checkboxField.label);\n\n this.scrollable.append(section.container);\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport toggleDisability from '../../../helpers/dom/toggleDisability';\nimport deepEqual from '../../../helpers/object/deepEqual';\nimport {ChannelParticipant, ChatParticipant} from '../../../layer';\nimport appDialogsManager from '../../../lib/appManagers/appDialogsManager';\nimport Button from '../../button';\nimport confirmationPopup from '../../confirmationPopup';\nimport SettingSection from '../../settingSection';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport getUserStatusString from '../../wrappers/getUserStatusString';\nimport wrapPeerTitle from '../../wrappers/peerTitle';\nimport {ChatPermissions} from './groupPermissions';\n\nexport default class AppUserPermissionsTab extends SliderSuperTabEventable {\n public participant: ChannelParticipant | ChatParticipant;\n public chatId: ChatId;\n public userId: UserId;\n\n public async init() {\n this.container.classList.add('edit-peer-container', 'user-permissions-container');\n this.setTitle('UserRestrictions');\n\n let destroyListener: () => void;\n\n const isChannel = await this.managers.appChatsManager.isChannel(this.chatId);\n\n {\n const section = new SettingSection({\n name: 'UserRestrictionsCanDo'\n });\n\n const div = document.createElement('div');\n div.classList.add('chatlist-container');\n section.content.insertBefore(div, section.title);\n\n const list = appDialogsManager.createChatList({new: true});\n div.append(list);\n\n const {dom} = appDialogsManager.addDialogNew({\n peerId: this.userId.toPeerId(false),\n container: list,\n rippleEnabled: true,\n avatarSize: 'abitbigger'\n });\n\n dom.lastMessageSpan.append(getUserStatusString(await this.managers.appUsersManager.getUser(this.userId)));\n\n const p = new ChatPermissions({\n chatId: this.chatId,\n listenerSetter: this.listenerSetter,\n appendTo: section.content,\n participant: this.participant._ === 'channelParticipantBanned' ? this.participant : undefined\n }, this.managers);\n\n destroyListener = () => {\n const rights = p.takeOut();\n if(this.participant._ === 'channelParticipantBanned' && deepEqual(this.participant.banned_rights.pFlags, rights.pFlags)) {\n return;\n }\n\n this.managers.appChatsManager.editBanned(this.chatId, this.participant, rights);\n };\n\n this.eventListener.addEventListener('destroy', destroyListener, {once: true});\n\n this.scrollable.append(section.container);\n }\n\n {\n const section = new SettingSection({});\n\n if(this.participant._ === 'channelParticipantBanned') {\n const btnDeleteException = Button('btn-primary btn-transparent danger', {icon: 'delete', text: 'GroupPermission.Delete'});\n\n attachClickEvent(btnDeleteException, () => {\n const toggle = toggleDisability([btnDeleteException], true);\n this.managers.appChatsManager.clearChannelParticipantBannedRights(\n this.chatId,\n this.participant as ChannelParticipant.channelParticipantBanned\n ).then(() => {\n this.eventListener.removeEventListener('destroy', destroyListener);\n this.close();\n }, () => {\n toggle();\n });\n }, {listenerSetter: this.listenerSetter});\n\n section.content.append(btnDeleteException);\n }\n\n const btnDelete = Button('btn-primary btn-transparent danger', {icon: 'deleteuser', text: 'UserRestrictionsBlock'});\n\n attachClickEvent(btnDelete, async() => {\n const toggle = toggleDisability([btnDelete], true);\n\n try {\n const peerId = this.userId.toPeerId();\n await confirmationPopup({\n peerId: this.chatId.toPeerId(true),\n descriptionLangKey: 'Permissions.RemoveFromGroup',\n descriptionLangArgs: [await wrapPeerTitle({peerId: peerId})],\n titleLangKey: 'ChannelBlockUser',\n button: {\n langKey: 'Remove',\n isDanger: true\n }\n });\n\n if(!isChannel) {\n await this.managers.appChatsManager.kickFromChat(this.chatId, this.participant);\n } else {\n await this.managers.appChatsManager.kickFromChannel(this.chatId, this.participant as ChannelParticipant);\n }\n } catch(err) {\n toggle();\n return;\n }\n\n this.eventListener.removeEventListener('destroy', destroyListener);\n this.close();\n }, {listenerSetter: this.listenerSetter});\n\n section.content.append(btnDelete);\n\n this.scrollable.append(section.container);\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {ChatRights} from '../../../lib/appManagers/appChatsManager';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport findUpTag from '../../../helpers/dom/findUpTag';\nimport replaceContent from '../../../helpers/dom/replaceContent';\nimport ListenerSetter from '../../../helpers/listenerSetter';\nimport ScrollableLoader from '../../../helpers/scrollableLoader';\nimport {ChannelParticipant, Chat, ChatBannedRights} from '../../../layer';\nimport appDialogsManager, {DialogDom, DIALOG_LIST_ELEMENT_TAG} from '../../../lib/appManagers/appDialogsManager';\nimport {AppManagers} from '../../../lib/appManagers/managers';\nimport combineParticipantBannedRights from '../../../lib/appManagers/utils/chats/combineParticipantBannedRights';\nimport hasRights from '../../../lib/appManagers/utils/chats/hasRights';\nimport getPeerActiveUsernames from '../../../lib/appManagers/utils/peers/getPeerActiveUsernames';\nimport getPeerId from '../../../lib/appManagers/utils/peers/getPeerId';\nimport {i18n, join, LangPackKey} from '../../../lib/langPack';\nimport rootScope from '../../../lib/rootScope';\nimport PopupPickUser from '../../popups/pickUser';\nimport Row from '../../row';\nimport SettingSection from '../../settingSection';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport {toast} from '../../toast';\nimport AppUserPermissionsTab from './userPermissions';\nimport CheckboxFields, {CheckboxFieldsField} from '../../checkboxFields';\nimport PopupElement from '../../popups';\n\ntype PermissionsCheckboxFieldsField = CheckboxFieldsField & {\n flags: ChatRights[],\n exceptionText: LangPackKey\n};\n\nexport class ChatPermissions extends CheckboxFields<PermissionsCheckboxFieldsField> {\n protected chat: Chat.chat | Chat.channel;\n protected rights: ChatBannedRights.chatBannedRights;\n protected defaultBannedRights: ChatBannedRights.chatBannedRights;\n protected restrictionText: LangPackKey;\n\n constructor(private options: {\n chatId: ChatId,\n listenerSetter: ListenerSetter,\n appendTo: HTMLElement,\n participant?: ChannelParticipant.channelParticipantBanned\n }, private managers: AppManagers) {\n super({\n listenerSetter: options.listenerSetter,\n fields: [],\n asRestrictions: true\n });\n\n this.construct();\n }\n\n public async construct() {\n const options = this.options;\n const chat = this.chat = await this.managers.appChatsManager.getChat(options.chatId) as Chat.chat | Chat.channel;\n const defaultBannedRights = this.defaultBannedRights = chat.default_banned_rights;\n const rights = this.rights = options.participant ? combineParticipantBannedRights(chat as Chat.channel, options.participant.banned_rights) : defaultBannedRights;\n\n const mediaNested: PermissionsCheckboxFieldsField[] = [\n {flags: ['send_photos'], text: 'UserRestrictionsSendPhotos', exceptionText: 'UserRestrictionsNoSendPhotos'},\n {flags: ['send_videos'], text: 'UserRestrictionsSendVideos', exceptionText: 'UserRestrictionsNoSendVideos'},\n {flags: ['send_stickers', 'send_gifs'], text: 'UserRestrictionsSendStickers', exceptionText: 'UserRestrictionsNoSendStickers'},\n {flags: ['send_audios'], text: 'UserRestrictionsSendMusic', exceptionText: 'UserRestrictionsNoSendMusic'},\n {flags: ['send_docs'], text: 'UserRestrictionsSendFiles', exceptionText: 'UserRestrictionsNoSendDocs'},\n {flags: ['send_voices'], text: 'UserRestrictionsSendVoices', exceptionText: 'UserRestrictionsNoSendVoice'},\n {flags: ['send_roundvideos'], text: 'UserRestrictionsSendRound', exceptionText: 'UserRestrictionsNoSendRound'},\n {flags: ['embed_links'], text: 'UserRestrictionsEmbedLinks', exceptionText: 'UserRestrictionsNoEmbedLinks'},\n {flags: ['send_polls'], text: 'UserRestrictionsSendPolls', exceptionText: 'UserRestrictionsNoSendPolls'}\n ];\n\n const mediaToggleWith = mediaNested;\n const v: PermissionsCheckboxFieldsField[] = [\n {flags: ['send_plain'], text: 'UserRestrictionsSend', exceptionText: 'UserRestrictionsNoSend'},\n {flags: ['send_media'], text: 'UserRestrictionsSendMedia', exceptionText: 'UserRestrictionsNoSendMedia', nested: mediaNested},\n {flags: ['invite_users'], text: 'UserRestrictionsInviteUsers', exceptionText: 'UserRestrictionsNoInviteUsers'},\n {flags: ['pin_messages'], text: 'UserRestrictionsPinMessages', exceptionText: 'UserRestrictionsNoPinMessages'},\n {flags: ['change_info'], text: 'UserRestrictionsChangeInfo', exceptionText: 'UserRestrictionsNoChangeInfo'}\n ];\n\n\n const map: {[action in ChatRights]?: PermissionsCheckboxFieldsField} = {};\n v.push(...mediaNested);\n v.forEach((info) => {\n const mainFlag = info.flags[0];\n map[mainFlag] = info;\n info.checked = hasRights(chat, mainFlag, rights)\n });\n\n mediaNested.forEach((info) => info.nestedTo = map.send_media);\n map.send_media.toggleWith = {unchecked: mediaToggleWith, checked: mediaToggleWith};\n map.embed_links.toggleWith = {checked: [map.send_plain]};\n map.send_plain.toggleWith = {unchecked: [map.embed_links]};\n\n this.fields = v;\n\n for(const info of this.fields) {\n if((\n this.options.participant &&\n defaultBannedRights.pFlags[info.flags[0] as keyof typeof defaultBannedRights['pFlags']]\n ) || (\n getPeerActiveUsernames(chat as Chat.channel)[0] &&\n (\n info.flags.includes('pin_messages') ||\n info.flags.includes('change_info')\n )\n )\n ) {\n info.restrictionText = this.restrictionText;\n }\n\n if(info.nestedTo) {\n continue;\n }\n\n const {nodes} = this.createField(info);\n options.appendTo.append(...nodes);\n }\n }\n\n public takeOut() {\n const rights: ChatBannedRights = {\n _: 'chatBannedRights',\n until_date: 0x7FFFFFFF,\n pFlags: {}\n };\n\n const IGNORE_FLAGS: Set<ChatRights> = new Set([\n 'send_media'\n ]);\n for(const info of this.fields) {\n const banned = !info.checkboxField.checked;\n if(!banned) {\n continue;\n }\n\n info.flags.forEach((flag) => {\n if(IGNORE_FLAGS.has(flag)) {\n return;\n }\n\n // @ts-ignore\n rights.pFlags[flag] = true;\n });\n }\n\n return rights;\n }\n}\n\nexport default class AppGroupPermissionsTab extends SliderSuperTabEventable {\n public chatId: ChatId;\n\n public async init() {\n this.container.classList.add('edit-peer-container', 'group-permissions-container');\n this.setTitle('ChannelPermissions');\n\n let chatPermissions: ChatPermissions;\n {\n const section = new SettingSection({\n name: 'ChannelPermissionsHeader'\n });\n\n chatPermissions = new ChatPermissions({\n chatId: this.chatId,\n listenerSetter: this.listenerSetter,\n appendTo: section.content\n }, this.managers);\n\n this.eventListener.addEventListener('destroy', () => {\n this.managers.appChatsManager.editChatDefaultBannedRights(this.chatId, chatPermissions.takeOut());\n }, {once: true});\n\n this.scrollable.append(section.container);\n }\n\n {\n const section = new SettingSection({\n name: 'PrivacyExceptions'\n });\n\n const addExceptionRow = new Row({\n titleLangKey: 'ChannelAddException',\n subtitleLangKey: 'Loading',\n icon: 'adduser',\n clickable: () => {\n PopupElement.createPopup(PopupPickUser, {\n peerTypes: ['channelParticipants'],\n onSelect: (peerId) => {\n setTimeout(() => {\n openPermissions(peerId);\n }, 0);\n },\n placeholder: 'ExceptionModal.Search.Placeholder',\n peerId: -this.chatId\n });\n },\n listenerSetter: this.listenerSetter\n });\n\n const openPermissions = async(peerId: PeerId) => {\n let participant: AppUserPermissionsTab['participant'];\n try {\n participant = await this.managers.appProfileManager.getParticipant(this.chatId, peerId);\n } catch(err) {\n toast('User is no longer participant');\n return;\n }\n\n const tab = this.slider.createTab(AppUserPermissionsTab);\n tab.participant = participant;\n tab.chatId = this.chatId;\n tab.userId = peerId;\n tab.open();\n };\n\n section.content.append(addExceptionRow.container);\n\n /* const removedUsersRow = new Row({\n titleLangKey: 'ChannelBlockedUsers',\n subtitleLangKey: 'NoBlockedUsers',\n icon: 'deleteuser',\n clickable: true\n });\n\n section.content.append(removedUsersRow.container); */\n\n const c = section.generateContentElement();\n c.classList.add('chatlist-container');\n\n const list = appDialogsManager.createChatList({new: true});\n c.append(list);\n\n attachClickEvent(list, (e) => {\n const target = findUpTag(e.target, DIALOG_LIST_ELEMENT_TAG);\n if(!target) return;\n\n const peerId = target.dataset.peerId.toPeerId();\n openPermissions(peerId);\n }, {listenerSetter: this.listenerSetter});\n\n const setSubtitle = async(dom: DialogDom, participant: ChannelParticipant.channelParticipantBanned) => {\n const bannedRights = participant.banned_rights;// appChatsManager.combineParticipantBannedRights(this.chatId, participant.banned_rights);\n const defaultBannedRights = ((await this.managers.appChatsManager.getChat(this.chatId)) as Chat.channel).default_banned_rights;\n // const combinedRights = appChatsManager.combineParticipantBannedRights(this.chatId, bannedRights);\n\n const cantWhat: LangPackKey[] = []/* , canWhat: LangPackKey[] = [] */;\n chatPermissions.fields.forEach((info) => {\n const mainFlag = info.flags[0];\n // @ts-ignore\n if(bannedRights.pFlags[mainFlag] && !defaultBannedRights.pFlags[mainFlag]) {\n cantWhat.push(info.exceptionText);\n // @ts-ignore\n }/* else if(!combinedRights.pFlags[mainFlag]) {\n canWhat.push(info.exceptionText);\n } */\n });\n\n const el = dom.lastMessageSpan as HTMLElement;\n\n if(cantWhat.length) {\n el.replaceChildren(...join(cantWhat.map((t) => i18n(t)), false));\n }/* else if(canWhat.length) {\n str = 'Can ' + canWhat.join(canWhat.length === 2 ? ' and ' : ', ');\n } */\n\n el.classList.toggle('hide', !cantWhat.length);\n };\n\n const add = (participant: ChannelParticipant.channelParticipantBanned, append: boolean) => {\n const {dom} = appDialogsManager.addDialogNew({\n peerId: getPeerId(participant.peer),\n container: list,\n rippleEnabled: true,\n avatarSize: 'abitbigger',\n append\n });\n\n (dom.listEl as any).dialogDom = dom;\n\n setSubtitle(dom, participant);\n };\n\n this.listenerSetter.add(rootScope)('chat_participant', (update) => {\n const needAdd = update.new_participant?._ === 'channelParticipantBanned' &&\n !update.new_participant.banned_rights.pFlags.view_messages;\n const li = list.querySelector(`[data-peer-id=\"${update.user_id}\"]`);\n if(needAdd) {\n if(!li) {\n add(update.new_participant as ChannelParticipant.channelParticipantBanned, false);\n } else {\n setSubtitle((li as any).dialogDom, update.new_participant as ChannelParticipant.channelParticipantBanned);\n }\n\n if(update.prev_participant?._ !== 'channelParticipantBanned') {\n ++exceptionsCount;\n }\n } else {\n li?.remove();\n\n if(update.prev_participant?._ === 'channelParticipantBanned') {\n --exceptionsCount;\n }\n }\n\n setLength();\n });\n\n const setLength = () => {\n replaceContent(addExceptionRow.subtitle, i18n(exceptionsCount ? 'Permissions.ExceptionsCount' : 'Permissions.NoExceptions', [exceptionsCount]));\n };\n\n let exceptionsCount = 0;\n let loader: ScrollableLoader;\n const setLoader = () => {\n const LOAD_COUNT = 50;\n loader = new ScrollableLoader({\n scrollable: this.scrollable,\n getPromise: () => {\n return this.managers.appProfileManager.getChannelParticipants(this.chatId, {_: 'channelParticipantsBanned', q: ''}, LOAD_COUNT, list.childElementCount).then((res) => {\n for(const participant of res.participants) {\n add(participant as ChannelParticipant.channelParticipantBanned, true);\n }\n\n exceptionsCount = res.count;\n setLength();\n\n return res.participants.length < LOAD_COUNT || res.count === list.childElementCount;\n });\n }\n });\n\n return loader.load();\n };\n\n this.scrollable.append(section.container);\n\n if(await this.managers.appChatsManager.isChannel(this.chatId)) {\n await setLoader();\n } else {\n setLength();\n\n this.listenerSetter.add(rootScope)('dialog_migrate', ({migrateFrom, migrateTo}) => {\n if(this.chatId === migrateFrom) {\n this.chatId = migrateTo;\n setLoader();\n }\n });\n }\n }\n }\n\n onOpenAfterTimeout() {\n this.scrollable.onScroll();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport copy from '../../../../helpers/object/copy';\nimport {ChatBannedRights, Chat} from '../../../../layer';\n\nexport default function combineParticipantBannedRights(chat: Chat.channel, rights: ChatBannedRights) {\n if(chat.default_banned_rights) {\n rights = copy(rights);\n const defaultRights = chat.default_banned_rights.pFlags;\n for(const i in defaultRights) {\n // @ts-ignore\n rights.pFlags[i] = defaultRights[i];\n }\n }\n\n return rights;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport replaceContent from '../../../helpers/dom/replaceContent';\nimport debounce from '../../../helpers/schedulers/debounce';\nimport {ChatReactions, Reaction} from '../../../layer';\nimport {i18n, LangPackKey} from '../../../lib/langPack';\nimport CheckboxField from '../../checkboxField';\nimport Row, {RadioFormFromValues} from '../../row';\nimport SettingSection from '../../settingSection';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport wrapStickerToRow from '../../wrappers/stickerToRow';\n\nexport default class AppChatReactionsTab extends SliderSuperTabEventable {\n public chatId: ChatId;\n\n public async init() {\n this.setTitle('Reactions');\n\n const availableReactions = await this.managers.appReactionsManager.getActiveAvailableReactions();\n const chatFull = await this.managers.appProfileManager.getChatFull(this.chatId);\n const isBroadcast = await this.managers.appChatsManager.isBroadcast(this.chatId);\n\n let _chatReactions = chatFull.available_reactions ?? {_: 'chatReactionsNone'};\n let chatReactions = _chatReactions;\n let emoticons = new Set(_chatReactions._ === 'chatReactionsSome' ? _chatReactions.reactions.map((reaction) => (reaction as Reaction.reactionEmoji).emoticon) : []);\n\n const makeReactionFromEmoticons = (emoticons: Array<string>): Reaction[] => emoticons.map((emoticon) => ({_: 'reactionEmoji', emoticon}));\n\n const getCaptionLangPackKey = (): LangPackKey => {\n if(isBroadcast) {\n return 'EnableReactionsChannelInfo';\n }\n\n return chatReactions._ === 'chatReactionsAll' ? 'EnableAllReactionsInfo' : (chatReactions._ === 'chatReactionsNone' ? 'DisableReactionsInfo' : 'EnableSomeReactionsInfo');\n };\n\n const toggleSection = new SettingSection({\n name: isBroadcast ? undefined : 'AvailableReactions',\n caption: getCaptionLangPackKey()\n });\n\n const reactionsSection = new SettingSection({\n name: 'OnlyAllowThisReactions'\n });\n\n const toggleCheckboxFieldsByEmoticons = () => {\n const r: Reaction.reactionEmoji[] = (chatReactions as ChatReactions.chatReactionsSome).reactions as any ?? [];\n emoticons = new Set(r.map(({emoticon}) => emoticon));\n checkboxFieldsByEmoticon.forEach((checkboxField, emoticon) => {\n checkboxField.setValueSilently(emoticons.has(emoticon));\n });\n };\n\n let toggleCheckboxField: CheckboxField;\n if(isBroadcast) {\n toggleCheckboxField = new CheckboxField({toggle: true, checked: _chatReactions._ === 'chatReactionsSome'});\n const toggleRow = new Row({\n checkboxField: toggleCheckboxField,\n titleLangKey: 'EnableReactions',\n listenerSetter: this.listenerSetter\n });\n\n toggleSection.content.append(toggleRow.container);\n\n this.listenerSetter.add(toggleCheckboxField.input)('change', () => {\n let save = true;\n if(!toggleCheckboxField.checked) {\n chatReactions = {_: 'chatReactionsNone'};\n } else if(checkboxFields.every((checkboxField) => !checkboxField.checked)) {\n chatReactions = {_: 'chatReactionsSome', reactions: makeReactionFromEmoticons(availableReactions.map(({reaction}) => reaction))};\n } else if(chatReactions._ !== 'chatReactionsSome') {\n chatReactions = {_: 'chatReactionsSome', reactions: makeReactionFromEmoticons(Array.from(emoticons))};\n } else {\n save = false;\n }\n\n if(save) {\n toggleCheckboxFieldsByEmoticons();\n saveReactionsDebounced();\n }\n });\n } else {\n const a: [ChatReactions['_'], LangPackKey][] = [\n ['chatReactionsAll', 'AllReactions'],\n ['chatReactionsSome', 'SomeReactions'],\n ['chatReactionsNone', 'NoReactions']\n ];\n\n const onChange = () => {\n reactionsSection.container.classList.toggle('hide', chatReactions._ !== 'chatReactionsSome');\n };\n\n let value = _chatReactions._;\n const form = RadioFormFromValues(a.map(([value, langPackKey]) => {\n return {\n langPackKey,\n value,\n checked: _chatReactions._ === value\n };\n }), (_value) => {\n value = _value as any;\n\n if(value === 'chatReactionsAll') {\n chatReactions = {\n _: value,\n pFlags: {\n allow_custom: true\n }\n };\n } else if(value === 'chatReactionsNone') {\n chatReactions = {\n _: value\n };\n } else {\n chatReactions = {\n _: value,\n reactions: makeReactionFromEmoticons(['👍', '👎'])\n };\n }\n\n replaceContent(toggleSection.caption, i18n(getCaptionLangPackKey()));\n toggleCheckboxFieldsByEmoticons();\n saveReactionsDebounced();\n onChange();\n });\n\n toggleSection.content.append(form);\n onChange();\n }\n\n const checkboxFieldsByEmoticon: Map<string, CheckboxField> = new Map();\n const checkboxFields = availableReactions.map((availableReaction) => {\n const emoticon = availableReaction.reaction;\n const checkboxField = new CheckboxField({\n toggle: true,\n checked: emoticons.has(emoticon)\n });\n\n checkboxFieldsByEmoticon.set(emoticon, checkboxField);\n\n this.listenerSetter.add(checkboxField.input)('change', () => {\n if(checkboxField.checked) {\n emoticons.add(emoticon);\n\n if(toggleCheckboxField && !toggleCheckboxField.checked) {\n toggleCheckboxField.checked = true;\n }\n } else {\n emoticons.delete(emoticon);\n\n if(toggleCheckboxField?.checked && !emoticons.size) {\n toggleCheckboxField.checked = false;\n }\n }\n\n saveReactionsDebounced();\n });\n\n const row = new Row({\n checkboxField,\n title: availableReaction.title,\n havePadding: true,\n listenerSetter: this.listenerSetter\n });\n\n wrapStickerToRow({\n row,\n doc: availableReaction.static_icon,\n size: 'small'\n });\n\n reactionsSection.content.append(row.container);\n\n return checkboxField;\n });\n\n const saveReactions = async() => {\n saveReactionsDebounced.clearTimeout();\n // const newReactions = Array.from(enabledReactions);\n // if([...newReactions].sort().join() === [...originalReactions].sort().join()) {\n // return;\n // }\n\n if(chatReactions._ === 'chatReactionsSome') {\n chatReactions.reactions = makeReactionFromEmoticons(Array.from(emoticons));\n }\n\n // const r = (chatReactions as ChatReactions.chatReactionsSome).reactions;\n // if(r?.length === availableReactions.length) {\n // chatReactions = {_: 'chatReactionsAll'};\n // }\n\n this.managers.appChatsManager.setChatAvailableReactions(this.chatId, chatReactions);\n _chatReactions = chatReactions;\n };\n\n const saveReactionsDebounced = debounce(saveReactions, 3000, false, true);\n\n this.eventListener.addEventListener('destroy', () => {\n if(saveReactionsDebounced.isDebounced()) {\n saveReactions();\n }\n }, {once: true});\n\n this.scrollable.append(toggleSection.container, reactionsSection.container);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SliderSuperTab} from '../../slider'\nimport InputField from '../../inputField';\nimport EditPeer from '../../editPeer';\nimport Row, {CreateRowFromCheckboxField} from '../../row';\nimport Button from '../../button';\nimport {ChatRights} from '../../../lib/appManagers/appChatsManager';\nimport {Chat, ChatFull} from '../../../layer';\nimport AppChatTypeTab from './chatType';\nimport rootScope from '../../../lib/rootScope';\nimport AppGroupPermissionsTab from './groupPermissions';\nimport {i18n, LangPackKey} from '../../../lib/langPack';\nimport PopupDeleteDialog from '../../popups/deleteDialog';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport toggleDisability from '../../../helpers/dom/toggleDisability';\nimport CheckboxField from '../../checkboxField';\nimport AppChatReactionsTab from './chatReactions';\nimport hasRights from '../../../lib/appManagers/utils/chats/hasRights';\nimport replaceContent from '../../../helpers/dom/replaceContent';\nimport SettingSection from '../../settingSection';\nimport getPeerActiveUsernames from '../../../lib/appManagers/utils/peers/getPeerActiveUsernames';\nimport PopupElement from '../../popups';\n\nexport default class AppEditChatTab extends SliderSuperTab {\n private chatNameInputField: InputField;\n private descriptionInputField: InputField;\n private editPeer: EditPeer;\n public chatId: ChatId;\n\n protected async _init() {\n // * cleanup prev\n this.listenerSetter.removeAll();\n this.scrollable.container.replaceChildren();\n\n this.container.classList.add('edit-peer-container', 'edit-group-container');\n this.setTitle('Edit');\n\n let [\n chatFull,\n chat,\n isBroadcast,\n isChannel,\n canChangeType,\n canChangePermissions,\n canManageTopics,\n appConfig\n ] = await Promise.all([\n this.managers.appProfileManager.getChatFull(this.chatId, true),\n this.managers.appChatsManager.getChat(this.chatId) as Promise<Chat.chat | Chat.channel>,\n this.managers.appChatsManager.isBroadcast(this.chatId),\n this.managers.appChatsManager.isChannel(this.chatId),\n this.managers.appChatsManager.hasRights(this.chatId, 'change_type'),\n this.managers.appChatsManager.hasRights(this.chatId, 'change_permissions'),\n this.managers.appChatsManager.hasRights(this.chatId, 'manage_topics'),\n this.managers.apiManager.getAppConfig()\n ]);\n\n const chatUpdateListeners: {[type in 'full' | 'basic']: (() => void)[]} = {full: [], basic: []};\n const addChatUpdateListener = (callback: () => void, type: 'full' | 'basic' = 'basic') => {\n chatUpdateListeners[type].push(callback);\n };\n\n this.listenerSetter.add(rootScope)('chat_update', async(chatId) => {\n if(this.chatId === chatId) {\n chat = await this.managers.appChatsManager.getChat(this.chatId) as typeof chat;\n chatUpdateListeners['basic'].forEach((callback) => callback());\n }\n });\n\n this.listenerSetter.add(rootScope)('chat_full_update', async(chatId) => {\n if(this.chatId === chatId) {\n chatFull = await this.managers.appProfileManager.getCachedFullChat(chatId) || chatFull;\n chatUpdateListeners['full'].forEach((callback) => callback());\n }\n });\n\n const peerId = this.chatId.toPeerId(true);\n\n {\n const section = new SettingSection({noDelimiter: true, caption: true});\n const inputFields: InputField[] = [];\n\n const inputWrapper = document.createElement('div');\n inputWrapper.classList.add('input-wrapper');\n\n this.chatNameInputField = new InputField({\n label: isBroadcast ? 'EnterChannelName' : 'CreateGroup.NameHolder',\n name: 'chat-name',\n maxLength: 255,\n required: true\n });\n this.descriptionInputField = new InputField({\n label: 'DescriptionPlaceholder',\n name: 'chat-description',\n maxLength: 255\n });\n\n this.chatNameInputField.setOriginalValue(chat.title);\n this.descriptionInputField.setOriginalValue(chatFull.about);\n\n inputWrapper.append(this.chatNameInputField.container, this.descriptionInputField.container);\n\n inputFields.push(this.chatNameInputField, this.descriptionInputField);\n\n this.editPeer = new EditPeer({\n peerId,\n inputFields,\n listenerSetter: this.listenerSetter,\n popupOptions: {isForum: (chat as Chat.channel).pFlags.forum}\n });\n this.content.append(this.editPeer.nextBtn);\n\n section.content.append(this.editPeer.avatarEdit.container, inputWrapper);\n\n if(canChangeType) {\n const chatTypeRow = new Row({\n titleLangKey: isBroadcast ? 'ChannelType' : 'GroupType',\n clickable: () => {\n const tab = this.slider.createTab(AppChatTypeTab);\n tab.chatId = this.chatId;\n tab.chatFull = chatFull;\n tab.open();\n },\n icon: 'lock',\n listenerSetter: this.listenerSetter\n });\n\n const setChatTypeSubtitle = () => {\n let key: LangPackKey;\n const username = getPeerActiveUsernames(chat as Chat.channel)[0];\n if(isBroadcast) {\n key = username ? 'TypePublic' : 'TypePrivate';\n } else {\n key = username ? 'TypePublicGroup' : 'TypePrivateGroup';\n }\n\n chatTypeRow.subtitle.replaceChildren(i18n(key));\n };\n\n setChatTypeSubtitle();\n addChatUpdateListener(setChatTypeSubtitle);\n section.content.append(chatTypeRow.container);\n }\n\n if(canChangeType || canChangePermissions) {\n const reactionsRow = new Row({\n titleLangKey: 'Reactions',\n icon: 'reactions',\n clickable: () => {\n const tab = this.slider.createTab(AppChatReactionsTab);\n tab.chatId = this.chatId;\n tab.open();\n },\n listenerSetter: this.listenerSetter\n });\n\n const availableReactions = await this.managers.appReactionsManager.getAvailableReactions();\n const availableReactionsLength = availableReactions.filter((availableReaction) => !availableReaction.pFlags.inactive).length;\n const setReactionsLength = () => {\n const chatAvailableReactions = chatFull.available_reactions ?? {_: 'chatReactionsNone'};\n if(chatAvailableReactions._ === 'chatReactionsSome') {\n const length = chatAvailableReactions.reactions.length;\n if(length === availableReactionsLength) {\n replaceContent(reactionsRow.subtitle, i18n('ReactionsAll'));\n } else {\n reactionsRow.subtitle.textContent = length + '/' + availableReactionsLength;\n }\n } else {\n replaceContent(reactionsRow.subtitle, i18n(chatAvailableReactions._ === 'chatReactionsAll' ? 'ReactionsAll' : 'Checkbox.Disabled'));\n }\n };\n\n setReactionsLength();\n addChatUpdateListener(setReactionsLength, 'full');\n section.content.append(reactionsRow.container);\n }\n\n if(canChangePermissions && !isBroadcast) {\n const flags = [\n 'send_stickers',\n 'send_polls',\n 'send_photos',\n 'send_videos',\n 'send_roundvideos',\n 'send_audios',\n 'send_voices',\n 'send_docs',\n 'send_plain',\n 'embed_links',\n 'invite_users',\n 'pin_messages',\n 'change_info'\n ] as ChatRights[];\n\n const permissionsRow = new Row({\n titleLangKey: 'ChannelPermissions',\n clickable: () => {\n const tab = this.slider.createTab(AppGroupPermissionsTab);\n tab.chatId = this.chatId;\n tab.open();\n },\n icon: 'permissions',\n listenerSetter: this.listenerSetter\n });\n\n const setPermissionsLength = () => {\n permissionsRow.subtitle.textContent = flags.reduce((acc, f) => acc + +hasRights(chat, f, (chat as Chat.chat).default_banned_rights), 0) + '/' + flags.length;\n };\n\n setPermissionsLength();\n addChatUpdateListener(setPermissionsLength);\n section.content.append(permissionsRow.container);\n }\n\n if(canManageTopics && (chat.participants_count >= appConfig.forum_upgrade_participants_min || (chat as Chat.channel).pFlags.forum) && !isBroadcast) {\n const topicsRow = new Row({\n checkboxField: new CheckboxField({toggle: true}),\n titleLangKey: 'Topics',\n clickable: () => {},\n icon: 'topics',\n listenerSetter: this.listenerSetter\n });\n\n const setTopics = () => {\n const isForum = !!(chat as Chat.channel).pFlags.forum;\n this.editPeer.avatarElem.parentElement.classList.toggle('is-forum', isForum);\n topicsRow.checkboxField.setValueSilently(isForum);\n };\n\n this.listenerSetter.add(topicsRow.checkboxField.input)('change', (e) => {\n if(!e.isTrusted) {\n return;\n }\n\n const promise = this.managers.appChatsManager.toggleForum(this.chatId, topicsRow.checkboxField.checked);\n topicsRow.disableWithPromise(promise);\n });\n\n setTopics();\n addChatUpdateListener(setTopics);\n\n section.caption.replaceChildren(i18n('ForumToggleDescription'));\n section.content.append(topicsRow.container);\n }\n\n section.caption.classList.toggle('hide', !section.caption.childElementCount);\n\n /* const administratorsRow = new Row({\n titleLangKey: 'PeerInfo.Administrators',\n subtitle: '' + ((chatFull as ChatFull.channelFull).admins_count || 1),\n icon: 'admin',\n clickable: true\n });\n\n section.content.append(administratorsRow.container); */\n\n this.scrollable.append(section.container);\n\n attachClickEvent(this.editPeer.nextBtn, () => {\n this.editPeer.nextBtn.disabled = true;\n\n const promises: Promise<any>[] = [];\n\n const id = this.chatId;\n if(this.chatNameInputField.isValidToChange()) {\n promises.push(this.managers.appChatsManager.editTitle(id, this.chatNameInputField.value));\n }\n\n if(this.descriptionInputField.isValidToChange()) {\n promises.push(this.managers.appChatsManager.editAbout(id, this.descriptionInputField.value));\n }\n\n if(this.editPeer.uploadAvatar) {\n promises.push(this.editPeer.uploadAvatar().then((inputFile) => {\n return this.managers.appChatsManager.editPhoto(id, inputFile);\n }));\n }\n\n Promise.race(promises).finally(() => {\n this.editPeer.nextBtn.removeAttribute('disabled');\n this.close();\n });\n }, {listenerSetter: this.listenerSetter});\n\n\n /* if(appChatsManager.hasRights(-this.peerId, 'change_info')) {\n const discussionRow = new Row({\n titleLangKey: 'PeerInfo.Discussion',\n subtitleLangKey: 'PeerInfo.Discussion.Add',\n clickable: true,\n icon: 'message'\n });\n\n section.content.append(discussionRow.container);\n }\n\n const administratorsRow = new Row({\n titleLangKey: 'PeerInfo.Administrators',\n subtitle: '' + chatFull.admins_count,\n icon: 'admin',\n clickable: true\n });\n\n section.content.append(administratorsRow.container); */\n\n if(isBroadcast && await this.managers.appChatsManager.hasRights(this.chatId, 'change_info')) {\n const signMessagesCheckboxField = new CheckboxField({\n text: 'ChannelSignMessages',\n checked: !!(chat as Chat.channel).pFlags.signatures\n });\n\n this.listenerSetter.add(signMessagesCheckboxField.input)('change', () => {\n const toggle = signMessagesCheckboxField.toggleDisability(true);\n this.managers.appChatsManager.toggleSignatures(this.chatId, signMessagesCheckboxField.checked).then(() => {\n toggle();\n });\n });\n\n addChatUpdateListener(() => {\n signMessagesCheckboxField.setValueSilently(!!(chat as Chat.channel).pFlags.signatures);\n });\n\n section.content.append(CreateRowFromCheckboxField(signMessagesCheckboxField).container);\n }\n }\n\n if(!isBroadcast) {\n const section = new SettingSection({\n\n });\n\n /* const membersRow = new Row({\n titleLangKey: isBroadcast ? 'PeerInfo.Subscribers' : 'GroupMembers',\n icon: 'newgroup',\n clickable: true\n });\n\n membersRow.subtitle.append(i18n('Subscribers', [numberThousandSplitter(335356)]));\n\n section.content.append(membersRow.container); */\n\n if(!isBroadcast && canChangeType) {\n const showChatHistoryCheckboxField = new CheckboxField({\n text: 'ChatHistory'\n });\n\n this.listenerSetter.add(showChatHistoryCheckboxField.input)('change', () => {\n const toggle = showChatHistoryCheckboxField.toggleDisability(true);\n this.managers.appChatsManager.togglePreHistoryHidden(this.chatId, !showChatHistoryCheckboxField.checked).then(() => {\n toggle();\n });\n });\n\n // ! it won't be updated because chatFull will be old\n const onChatUpdate = () => {\n showChatHistoryCheckboxField.setValueSilently(isChannel && !(chatFull as ChatFull.channelFull).pFlags.hidden_prehistory);\n };\n\n onChatUpdate();\n addChatUpdateListener(onChatUpdate);\n\n section.content.append(CreateRowFromCheckboxField(showChatHistoryCheckboxField).container);\n }\n\n if(section.content.childElementCount) {\n this.scrollable.append(section.container);\n }\n }\n\n if(await this.managers.appChatsManager.hasRights(this.chatId, 'delete_chat')) {\n const section = new SettingSection({});\n\n const btnDelete = Button('btn-primary btn-transparent danger', {icon: 'delete', text: isBroadcast ? 'PeerInfo.DeleteChannel' : 'DeleteAndExitButton'});\n\n attachClickEvent(btnDelete, () => {\n PopupElement.createPopup(PopupDeleteDialog, peerId/* , 'delete' */, undefined, (promise) => {\n const toggle = toggleDisability([btnDelete], true);\n promise.then(() => {\n this.close();\n }, () => {\n toggle();\n });\n });\n }, {listenerSetter: this.listenerSetter});\n\n section.content.append(btnDelete);\n\n this.scrollable.append(section.container);\n }\n\n if(!isChannel) {\n // ! this one will fire earlier than tab's closeAfterTimeout (destroy) event and listeners will be erased, so destroy won't fire\n this.listenerSetter.add(rootScope)('dialog_migrate', ({migrateFrom, migrateTo}) => {\n if(peerId === migrateFrom) {\n this.chatId = migrateTo.toChatId();\n this._init();\n }\n });\n }\n }\n\n public init() {\n return this._init();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport rootScope from '../../../lib/rootScope';\nimport AppSearchSuper, {SearchSuperType} from '../../appSearchSuper.';\nimport SidebarSlider, {SliderSuperTab} from '../../slider';\nimport TransitionSlider from '../../transition';\nimport AppEditChatTab from './editChat';\nimport PeerTitle from '../../peerTitle';\nimport AppEditContactTab from './editContact';\nimport Button from '../../button';\nimport ButtonIcon from '../../buttonIcon';\nimport I18n, {i18n, LangPackKey} from '../../../lib/langPack';\nimport {toastNew} from '../../toast';\nimport AppAddMembersTab from '../../sidebarLeft/tabs/addMembers';\nimport PopupPickUser from '../../popups/pickUser';\nimport PopupPeer, {PopupPeerButtonCallbackCheckboxes, PopupPeerCheckboxOptions} from '../../popups/peer';\nimport ButtonCorner from '../../buttonCorner';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport PeerProfile from '../../peerProfile';\nimport {Message} from '../../../layer';\nimport getMessageThreadId from '../../../lib/appManagers/utils/messages/getMessageThreadId';\nimport AppEditTopicTab from './editTopic';\nimport liteMode from '../../../helpers/liteMode';\nimport PopupElement from '../../popups';\n\ntype SharedMediaHistoryStorage = Partial<{\n [type in SearchSuperType]: {mid: number, peerId: PeerId}[]\n}>;\n\nconst historiesStorage: {\n [peerId: PeerId]: {\n [threadId: number]: SharedMediaHistoryStorage\n }\n} = {};\n\n// TODO: отредактированное сообщение не изменится\nexport default class AppSharedMediaTab extends SliderSuperTab {\n private editBtn: HTMLElement;\n\n private peerId: PeerId;\n private threadId: number;\n\n private searchSuper: AppSearchSuper;\n\n private profile: PeerProfile;\n private peerChanged: boolean;\n\n private titleI18n: I18n.IntlElement;\n\n public isFirst: boolean;\n\n public init() {\n // const perf = performance.now();\n\n this.container.classList.add('shared-media-container', 'profile-container');\n\n // * header\n const newCloseBtn = Button('btn-icon sidebar-close-button', {noRipple: true});\n this.closeBtn.replaceWith(newCloseBtn);\n this.closeBtn = newCloseBtn;\n\n const animatedCloseIcon = document.createElement('div');\n animatedCloseIcon.classList.add('animated-close-icon');\n newCloseBtn.append(animatedCloseIcon);\n\n if(this.isFirst) {\n animatedCloseIcon.classList.add('state-back');\n }\n\n const transitionContainer = document.createElement('div');\n transitionContainer.className = 'transition slide-fade';\n\n const transitionFirstItem = document.createElement('div');\n transitionFirstItem.classList.add('transition-item');\n\n this.titleI18n = new I18n.IntlElement();\n this.title.append(this.titleI18n.element);\n this.editBtn = ButtonIcon('edit');\n // const moreBtn = ButtonIcon('more');\n\n transitionFirstItem.append(this.title, this.editBtn/* , moreBtn */);\n\n const transitionLastItem = document.createElement('div');\n transitionLastItem.classList.add('transition-item');\n\n const secondTitle: HTMLElement = this.title.cloneNode() as any;\n secondTitle.append(i18n('PeerInfo.SharedMedia'));\n\n transitionLastItem.append(secondTitle);\n\n transitionContainer.append(transitionFirstItem, transitionLastItem);\n\n this.header.append(transitionContainer);\n\n // * body\n\n this.profile = new PeerProfile(this.managers, this.scrollable, this.listenerSetter);\n this.profile.init();\n\n this.scrollable.append(this.profile.element);\n\n const HEADER_HEIGHT = 56;\n this.scrollable.onAdditionalScroll = () => {\n const rect = this.searchSuper.nav.getBoundingClientRect();\n if(!rect.width) return;\n\n const top = rect.top - 1;\n setIsSharedMedia(top <= HEADER_HEIGHT);\n };\n\n const setIsSharedMedia = (isSharedMedia: boolean) => {\n animatedCloseIcon.classList.toggle('state-back', this.isFirst || isSharedMedia);\n this.searchSuper.container.classList.toggle('is-full-viewport', isSharedMedia);\n transition(+isSharedMedia);\n\n if(!isSharedMedia) {\n this.searchSuper.cleanScrollPositions();\n }\n };\n\n const transition = TransitionSlider({\n content: transitionContainer,\n type: 'slide-fade',\n transitionTime: 400,\n isHeavy: false\n });\n\n transition(0);\n\n attachClickEvent(this.closeBtn, (e) => {\n if(transition.prevId()) {\n this.scrollable.scrollIntoViewNew({\n element: this.scrollable.container.firstElementChild as HTMLElement,\n position: 'start'\n });\n transition(0);\n\n if(!this.isFirst) {\n animatedCloseIcon.classList.remove('state-back');\n }\n } else if(!this.scrollable.isHeavyAnimationInProgress) {\n this.slider.onCloseBtnClick();\n }\n }, {listenerSetter: this.listenerSetter});\n\n attachClickEvent(this.editBtn, async() => {\n let tab: AppEditChatTab | AppEditContactTab | AppEditTopicTab;\n const {peerId, threadId} = this;\n if(threadId && await this.managers.appPeersManager.isForum(peerId)) {\n tab = this.slider.createTab(AppEditTopicTab)\n } else if(peerId.isAnyChat()) {\n tab = this.slider.createTab(AppEditChatTab);\n } else {\n tab = this.slider.createTab(AppEditContactTab);\n }\n\n if(tab) {\n if(tab instanceof AppEditTopicTab) {\n tab.open(peerId, this.threadId);\n } else {\n if(tab instanceof AppEditChatTab) {\n tab.chatId = peerId.toChatId();\n } else {\n tab.peerId = peerId;\n }\n\n tab.open();\n }\n }\n }, {listenerSetter: this.listenerSetter});\n\n this.listenerSetter.add(rootScope)('contacts_update', (userId) => {\n if(this.peerId === userId) {\n this.toggleEditBtn();\n }\n });\n\n this.listenerSetter.add(rootScope)('chat_update', (chatId) => {\n if(this.peerId === chatId.toPeerId(true)) {\n this.toggleEditBtn();\n }\n });\n\n this.listenerSetter.add(rootScope)('history_multiappend', (message) => {\n this.renderNewMessage(message);\n });\n\n this.listenerSetter.add(rootScope)('history_delete', ({peerId, msgs}) => {\n this.deleteDeletedMessages(peerId, Array.from(msgs));\n });\n\n // Calls when message successfully sent and we have an id\n this.listenerSetter.add(rootScope)('message_sent', ({message}) => {\n this.renderNewMessage(message);\n });\n\n // this.container.prepend(this.closeBtn.parentElement);\n\n this.searchSuper = new AppSearchSuper({\n mediaTabs: [{\n inputFilter: 'inputMessagesFilterEmpty',\n name: 'PeerMedia.Members',\n type: 'members'\n }, {\n inputFilter: 'inputMessagesFilterPhotoVideo',\n name: 'SharedMediaTab2',\n type: 'media'\n }, {\n inputFilter: 'inputMessagesFilterDocument',\n name: 'SharedFilesTab2',\n type: 'files'\n }, {\n inputFilter: 'inputMessagesFilterUrl',\n name: 'SharedLinksTab2',\n type: 'links'\n }, {\n inputFilter: 'inputMessagesFilterMusic',\n name: 'SharedMusicTab2',\n type: 'music'\n }, {\n inputFilter: 'inputMessagesFilterRoundVoice',\n name: 'SharedVoiceTab2',\n type: 'voice'\n }, {\n inputFilter: 'inputMessagesFilterEmpty',\n name: 'ChatList.Filter.Groups',\n type: 'groups'\n }],\n scrollable: this.scrollable,\n onChangeTab: (mediaTab) => {\n const timeout = mediaTab.type === 'members' && liteMode.isAvailable('animations') ? 250 : 0;\n setTimeout(() => {\n btnAddMembers.classList.toggle('is-hidden', mediaTab.type !== 'members');\n }, timeout);\n },\n managers: this.managers\n });\n\n this.searchSuper.scrollStartCallback = () => {\n setIsSharedMedia(true);\n };\n\n this.profile.element.append(this.searchSuper.container);\n\n const btnAddMembers = ButtonCorner({icon: 'addmember_filled'});\n this.content.append(btnAddMembers);\n\n attachClickEvent(btnAddMembers, async() => {\n const peerId = this.peerId;\n const id = this.peerId.toChatId();\n const isChannel = await this.managers.appChatsManager.isChannel(id);\n\n const showConfirmation = (peerIds: PeerId[], callback: (checked: PopupPeerButtonCallbackCheckboxes) => void) => {\n let titleLangKey: LangPackKey, titleLangArgs: any[],\n descriptionLangKey: LangPackKey, descriptionLangArgs: any[],\n checkboxes: PopupPeerCheckboxOptions[];\n\n if(peerIds.length > 1) {\n titleLangKey = 'AddMembersAlertTitle';\n titleLangArgs = [i18n('Members', [peerIds.length])];\n descriptionLangKey = 'AddMembersAlertCountText';\n descriptionLangArgs = peerIds.map((peerId) => {\n const b = document.createElement('b');\n b.append(new PeerTitle({peerId}).element);\n return b;\n });\n\n if(!isChannel) {\n checkboxes = [{\n text: 'AddMembersForwardMessages',\n checked: true\n }];\n }\n } else {\n titleLangKey = 'AddOneMemberAlertTitle';\n descriptionLangKey = 'AddMembersAlertNamesText';\n const b = document.createElement('b');\n b.append(new PeerTitle({\n peerId: peerIds[0]\n }).element);\n descriptionLangArgs = [b];\n\n if(!isChannel) {\n checkboxes = [{\n text: 'AddOneMemberForwardMessages',\n textArgs: [new PeerTitle({peerId: peerIds[0]}).element],\n checked: true\n }];\n }\n }\n\n descriptionLangArgs.push(new PeerTitle({\n peerId\n }).element);\n\n PopupElement.createPopup(PopupPeer, 'popup-add-members', {\n peerId,\n titleLangKey,\n descriptionLangKey,\n descriptionLangArgs,\n buttons: [{\n langKey: 'Add',\n callback\n }],\n checkboxes\n }).show();\n };\n\n const onError = (err: any) => {\n if(err.type === 'USER_PRIVACY_RESTRICTED') {\n toastNew({langPackKey: 'InviteToGroupError'});\n }\n };\n\n if(isChannel) {\n const tab = this.slider.createTab(AppAddMembersTab);\n tab.open({\n type: 'channel',\n skippable: false,\n takeOut: (peerIds) => {\n showConfirmation(peerIds, () => {\n const promise = this.managers.appChatsManager.inviteToChannel(id, peerIds);\n promise.catch(onError);\n tab.attachToPromise(promise);\n });\n\n return false;\n },\n title: 'GroupAddMembers',\n placeholder: 'SendMessageTo'\n });\n } else {\n PopupElement.createPopup(PopupPickUser, {\n peerTypes: ['contacts'],\n placeholder: 'Search',\n onSelect: (peerId) => {\n setTimeout(() => {\n showConfirmation([peerId], (checked) => {\n this.managers.appChatsManager.addChatUser(id, peerId, checked.size ? undefined : 0)\n .catch(onError);\n });\n }, 0);\n }\n });\n }\n }, {listenerSetter: this.listenerSetter});\n\n // console.log('construct shared media time:', performance.now() - perf);\n }\n\n private _renderNewMessage(message: Message.message | Message.messageService, threadId?: number) {\n const historyStorage = historiesStorage[message.peerId]?.[threadId];\n if(!historyStorage) return;\n\n for(const mediaTab of this.searchSuper.mediaTabs) {\n const inputFilter = mediaTab.inputFilter;\n const history = historyStorage[inputFilter];\n if(!history) {\n continue;\n }\n\n const filtered = this.searchSuper.filterMessagesByType([message], inputFilter)\n .filter((message) => !history.find((m) => m.mid === message.mid && m.peerId === message.peerId));\n if(filtered.length) {\n history.unshift(...filtered.map((message) => ({mid: message.mid, peerId: message.peerId})));\n\n if(this.peerId === message.peerId && this.searchSuper.usedFromHistory[inputFilter] !== -1) {\n this.searchSuper.usedFromHistory[inputFilter] += filtered.length;\n this.searchSuper.performSearchResult(filtered, mediaTab, false);\n }\n }\n }\n }\n\n private async renderNewMessage(message: Message.message | Message.messageService) {\n if(this.init) return; // * not inited yet\n\n const {peerId} = message;\n const isForum = await this.managers.appPeersManager.isForum(peerId);\n const threadId = getMessageThreadId(message, isForum);\n\n this._renderNewMessage(message);\n if(threadId) {\n this._renderNewMessage(message, threadId);\n }\n }\n\n public _deleteDeletedMessages(historyStorage: SharedMediaHistoryStorage, peerId: PeerId, mids: number[]) {\n for(const mid of mids) {\n for(const type of this.searchSuper.mediaTabs) {\n const inputFilter = type.inputFilter;\n\n const history = historyStorage[inputFilter];\n if(!history) continue;\n\n const idx = history.findIndex((m) => m.mid === mid);\n if(idx === -1) {\n continue;\n }\n\n history.splice(idx, 1);\n\n if(this.peerId === peerId) {\n const container = this.searchSuper.tabs[inputFilter];\n const div = container.querySelector(`[data-mid=\"${mid}\"][data-peer-id=\"${peerId}\"]`) as HTMLElement;\n if(div) {\n if(this.searchSuper.selection.isSelecting) {\n this.searchSuper.selection.toggleByElement(div);\n }\n\n div.remove();\n }\n\n if(this.searchSuper.usedFromHistory[inputFilter] >= (idx + 1)) {\n --this.searchSuper.usedFromHistory[inputFilter];\n }\n }\n\n // can have element in different tabs somehow\n // break;\n }\n }\n }\n\n public deleteDeletedMessages(peerId: PeerId, mids: number[]) {\n if(this.init) return; // * not inited yet\n\n const h = historiesStorage[peerId];\n if(!h) return;\n\n for(const threadId in h) {\n this._deleteDeletedMessages(h[threadId], peerId, mids);\n }\n\n this.scrollable.onScroll();\n }\n\n private async cleanupHTML() {\n // const perf = performance.now();\n const isAnyChat = this.peerId.isAnyChat();\n const [canViewMembers, hasRights] = await Promise.all([\n isAnyChat ? this.searchSuper.canViewMembers() : false,\n isAnyChat ? this.managers.appChatsManager.hasRights(this.peerId.toChatId(), 'invite_users') : false\n ]);\n\n return () => {\n this.profile.cleanupHTML();\n this.editBtn.classList.add('hide');\n this.searchSuper.cleanupHTML(true);\n this.container.classList.toggle('can-add-members', canViewMembers && hasRights);\n };\n // console.log('cleanupHTML shared media time:', performance.now() - perf);\n }\n\n public setLoadMutex(promise: Promise<any>) {\n this.searchSuper.loadMutex = promise;\n }\n\n public setPeer(peerId: PeerId, threadId?: number) {\n if(this.peerId === peerId && this.threadId === threadId) return false;\n\n this.peerId = peerId;\n this.threadId = threadId;\n this.peerChanged = true;\n\n if(this.init) {\n this.init();\n this.init = null;\n }\n\n this.searchSuper.setQuery({\n peerId,\n threadId,\n historyStorage: (historiesStorage[peerId] ??= {})[threadId] ??= {}\n });\n\n this.profile.setPeer(peerId, threadId);\n\n return true;\n }\n\n private async changeTitleKey() {\n const isForum = this.managers.appPeersManager.isForum(this.peerId);\n\n return () => {\n this.titleI18n.compareAndUpdate({key: this.threadId && isForum ? 'AccDescrTopic' : 'Profile'});\n };\n }\n\n public async fillProfileElements() {\n if(!this.peerChanged) {\n return;\n }\n\n this.peerChanged = false;\n const callbacks = await Promise.all([\n this.cleanupHTML(),\n this.toggleEditBtn(true),\n this.profile.fillProfileElements(),\n this.changeTitleKey()\n ]);\n\n return () => {\n callbacks.forEach((callback) => {\n callback?.();\n });\n };\n }\n\n private async toggleEditBtn<T extends boolean>(manual?: T): Promise<T extends true ? () => void : void> {\n let show: boolean;\n if(this.peerId.isUser()) {\n show = this.peerId !== rootScope.myId && await this.managers.appUsersManager.isContact(this.peerId.toUserId());\n } else {\n const chatId = this.peerId.toChatId();\n const isTopic = this.threadId && await this.managers.appChatsManager.isForum(chatId);\n show = await this.managers.appChatsManager.hasRights(chatId, isTopic ? 'manage_topics' : 'change_info');\n }\n\n const callback = () => {\n this.editBtn.classList.toggle('hide', !show);\n };\n\n return manual ? callback : callback() as any;\n }\n\n public loadSidebarMedia(single: boolean, justLoad?: boolean) {\n this.searchSuper.load(single, justLoad);\n }\n\n onOpenAfterTimeout() {\n super.onOpenAfterTimeout();\n\n this.scrollable.onScroll();\n }\n\n onCloseAfterTimeout() {\n super.onCloseAfterTimeout();\n\n if(this.destroyable) {\n this.profile.destroy();\n this.searchSuper.destroy();\n }\n }\n\n public destroy() {\n this.destroyable = true;\n this.onCloseAfterTimeout();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport liteMode from '../helpers/liteMode';\nimport rootScope from '../lib/rootScope';\n\ntype SetTransitionOptions = {\n element: HTMLElement,\n className: string,\n forwards: boolean,\n duration: number,\n onTransitionEnd?: () => void,\n useRafs?: number,\n onTransitionStart?: () => void\n};\nconst SetTransition = (options: SetTransitionOptions) => {\n const {element, className, forwards, duration, onTransitionEnd, onTransitionStart, useRafs} = options;\n const {timeout, raf} = element.dataset;\n if(timeout !== undefined) {\n clearTimeout(+timeout);\n }\n\n // useRafs = undefined;\n // duration = 0;\n\n if(raf !== undefined) {\n window.cancelAnimationFrame(+raf);\n if(!useRafs) {\n delete element.dataset.raf;\n }\n }\n\n // if(forwards && className && element.classList.contains(className) && !element.classList.contains('animating')) {\n // return;\n // }\n\n if(useRafs && liteMode.isAvailable('animations') && duration) {\n element.dataset.raf = '' + window.requestAnimationFrame(() => {\n delete element.dataset.raf;\n SetTransition({\n ...options,\n useRafs: useRafs - 1\n });\n });\n\n return;\n }\n\n if(forwards && className) {\n element.classList.add(className);\n }\n\n const afterTimeout = () => {\n delete element.dataset.timeout;\n if(!forwards && className) {\n element.classList.remove('backwards', className);\n }\n\n element.classList.remove('animating');\n\n onTransitionEnd?.();\n };\n\n onTransitionStart?.();\n if(!liteMode.isAvailable('animations') || !duration) {\n element.classList.remove('animating', 'backwards');\n afterTimeout();\n return;\n }\n\n element.classList.add('animating');\n\n element.classList.toggle('backwards', !forwards);\n element.dataset.timeout = '' + setTimeout(afterTimeout, duration);\n};\n\nexport default SetTransition;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {horizontalMenu} from './horizontalMenu';\nimport TransitionSlider from './transition';\nimport appNavigationController, {NavigationItem} from './appNavigationController';\nimport SliderSuperTab, {SliderSuperTabConstructable} from './sliderTab';\nimport indexOfAndSplice from '../helpers/array/indexOfAndSplice';\nimport safeAssign from '../helpers/object/safeAssign';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport {getMiddleware, MiddlewareHelper} from '../helpers/middleware';\nimport {MaybePromise} from '../types';\n\nconst TRANSITION_TIME = 250;\n\nexport {SliderSuperTab};\n\nexport default class SidebarSlider {\n protected _selectTab: ReturnType<typeof horizontalMenu>;\n protected historyTabIds: (number | SliderSuperTab)[] = []; // * key is any, since right sidebar is ugly nowz\n protected tabsContainer: HTMLElement;\n public sidebarEl: HTMLElement;\n protected tabs: Map<any, SliderSuperTab>; // * key is any, since right sidebar is ugly now\n private canHideFirst = false;\n private navigationType: NavigationItem['type'];\n protected managers: AppManagers;\n protected middlewareHelper: MiddlewareHelper;\n public onOpenTab: () => MaybePromise<void>;\n\n constructor(options: {\n sidebarEl: SidebarSlider['sidebarEl'],\n tabs?: SidebarSlider['tabs'],\n canHideFirst?: SidebarSlider['canHideFirst'],\n navigationType: SidebarSlider['navigationType']\n }) {\n safeAssign(this, options);\n\n this.tabs ??= new Map();\n\n this.tabsContainer = this.sidebarEl.querySelector('.sidebar-slider');\n this._selectTab = TransitionSlider({\n content: this.tabsContainer,\n type: 'navigation',\n transitionTime: TRANSITION_TIME\n });\n if(!this.canHideFirst) {\n this._selectTab(0);\n }\n\n this.middlewareHelper = getMiddleware();\n\n // Array.from(this.sidebarEl.querySelectorAll('.sidebar-close-button') as any as HTMLElement[]).forEach((el) => {\n // attachClickEvent(el, this.onCloseBtnClick);\n // });\n }\n\n public getMiddleware() {\n return this.middlewareHelper.get();\n }\n\n public onCloseBtnClick = () => {\n const item = appNavigationController.findItemByType(this.navigationType);\n if(item) {\n appNavigationController.back(this.navigationType);\n } else if(this.historyTabIds.length) {\n this.closeTab(this.historyTabIds[this.historyTabIds.length - 1]);\n }\n // this.closeTab();\n };\n\n public closeTab = (id?: number | SliderSuperTab, animate?: boolean, isNavigation?: boolean) => {\n if(id !== undefined && this.historyTabIds[this.historyTabIds.length - 1] !== id) {\n this.removeTabFromHistory(id);\n return false;\n }\n\n // console.log('sidebar-close-button click:', this.historyTabIDs);\n const closingId = this.historyTabIds.pop(); // pop current\n this.onCloseTab(closingId, animate, isNavigation);\n\n const tab = this.historyTabIds[this.historyTabIds.length - 1];\n this._selectTab(tab !== undefined ? (tab instanceof SliderSuperTab ? tab.container : tab) : (this.canHideFirst ? -1 : 0), animate);\n return true;\n };\n\n public async selectTab(id: number | SliderSuperTab) {\n /* if(id instanceof SliderSuperTab) {\n id = id.id;\n } */\n\n if(this.historyTabIds[this.historyTabIds.length - 1] === id) {\n return false;\n }\n\n const tab: SliderSuperTab = id instanceof SliderSuperTab ? id : this.tabs.get(id);\n this.onOpenTab && await this.onOpenTab();\n\n if(tab) {\n // @ts-ignore\n tab.onOpen?.();\n\n // @ts-ignore\n if(tab.onOpenAfterTimeout) {\n setTimeout(() => {\n // @ts-ignore\n tab.onOpenAfterTimeout();\n }, TRANSITION_TIME);\n }\n }\n\n // if(!this.canHideFirst || this.historyTabIds.length) {\n appNavigationController.pushItem({\n type: this.navigationType,\n onPop: (canAnimate) => {\n this.closeTab(undefined, canAnimate, true);\n return true;\n }\n });\n // }\n\n this.historyTabIds.push(id);\n this._selectTab(id instanceof SliderSuperTab ? id.container : id);\n return true;\n }\n\n public removeTabFromHistory(id: number | SliderSuperTab) {\n indexOfAndSplice(this.historyTabIds, id);\n this.onCloseTab(id, undefined);\n }\n\n public sliceTabsUntilTab(tabConstructor: SliderSuperTabConstructable, preserveTab: SliderSuperTab) {\n for(let i = this.historyTabIds.length - 1; i >= 0; --i) {\n const tab = this.historyTabIds[i];\n if(tab === preserveTab) continue;\n else if(tab instanceof tabConstructor) {\n break;\n }\n\n this.removeTabFromHistory(tab);\n // appNavigationController.removeByType(this.navigationType, true);\n }\n }\n\n public getTab<T extends SliderSuperTab>(tabConstructor: SliderSuperTabConstructable<T>) {\n return this.historyTabIds.find((t) => t instanceof tabConstructor) as T;\n }\n\n public getHistory() {\n return this.historyTabIds;\n }\n\n public isTabExists(tabConstructor: SliderSuperTabConstructable) {\n return !!this.getTab(tabConstructor);\n }\n\n protected onCloseTab(id: number | SliderSuperTab, animate: boolean, isNavigation?: boolean) {\n if(!isNavigation) {\n appNavigationController.removeByType(this.navigationType, true);\n }\n\n const tab: SliderSuperTab = id instanceof SliderSuperTab ? id : this.tabs.get(id);\n if(tab) {\n try {\n // @ts-ignore\n tab.onClose?.();\n } catch(err) {\n console.error('tab onClose error', tab);\n }\n\n // @ts-ignore\n if(tab.onCloseAfterTimeout) {\n setTimeout(() => {\n // @ts-ignore\n tab.onCloseAfterTimeout();\n }, TRANSITION_TIME + 30);\n }\n }\n }\n\n public addTab(tab: SliderSuperTab) {\n if(!tab.container.parentElement) {\n this.tabsContainer.append(tab.container);\n\n if(tab.closeBtn) {\n tab.closeBtn.addEventListener('click', this.onCloseBtnClick);\n }\n }\n }\n\n public deleteTab(tab: SliderSuperTab) {\n this.tabs.delete(tab);\n }\n\n public createTab<T extends SliderSuperTab>(\n ctor: SliderSuperTabConstructable<T>,\n destroyable = true,\n doNotAppend?: boolean\n ) {\n const tab = new ctor(doNotAppend ? undefined : this, destroyable);\n tab.managers = this.managers;\n return tab;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport EventListenerBase from '../helpers/eventListenerBase';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport {getMiddleware, MiddlewareHelper} from '../helpers/middleware';\nimport noop from '../helpers/noop';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport {i18n, LangPackKey} from '../lib/langPack';\nimport ButtonIcon from './buttonIcon';\nimport Scrollable from './scrollable';\nimport SidebarSlider from './slider';\n\nexport interface SliderSuperTabConstructable<T extends SliderSuperTab = any> {\n new(slider: SidebarSlider, destroyable: boolean): T;\n}\n\nexport interface SliderSuperTabEventableConstructable {\n new(slider: SidebarSlider, destroyable: boolean): SliderSuperTabEventable;\n}\n\nexport default class SliderSuperTab {\n public static getInitArgs?(fromTab: SliderSuperTab): any;\n\n public container: HTMLElement;\n\n public header: HTMLElement;\n public closeBtn: HTMLElement;\n public title: HTMLElement;\n\n public content: HTMLElement;\n public scrollable: Scrollable;\n\n public slider: SidebarSlider;\n public destroyable: boolean;\n public listenerSetter: ListenerSetter;\n\n public managers: AppManagers;\n public middlewareHelper: MiddlewareHelper;\n\n constructor(slider: SidebarSlider, destroyable?: boolean) {\n this._constructor(slider, destroyable);\n }\n\n public _constructor(slider: SidebarSlider, destroyable = true): any {\n this.slider = slider;\n this.middlewareHelper = slider ? slider.getMiddleware().create() : getMiddleware();\n this.destroyable = destroyable;\n\n this.container = document.createElement('div');\n this.container.classList.add('tabs-tab', 'sidebar-slider-item');\n\n // * Header\n this.header = document.createElement('div');\n this.header.classList.add('sidebar-header');\n\n this.closeBtn = ButtonIcon('left sidebar-close-button', {noRipple: true});\n this.title = document.createElement('div');\n this.title.classList.add('sidebar-header__title');\n this.header.append(this.closeBtn, this.title);\n\n // * Content\n this.content = document.createElement('div');\n this.content.classList.add('sidebar-content');\n\n this.scrollable = new Scrollable(this.content, undefined, undefined, true);\n this.scrollable.attachBorderListeners(this.container);\n\n this.container.append(this.header, this.content);\n\n this.slider?.addTab(this);\n\n this.listenerSetter = new ListenerSetter();\n }\n\n public close() {\n return this.slider.closeTab(this);\n }\n\n public async open(...args: Parameters<typeof this['init']>) {\n if(this.init) {\n try {\n const result = this.init(...args);\n this.init = null;\n\n if(result instanceof Promise) {\n await result;\n }\n } catch(err) {\n console.error('open tab error', err);\n }\n }\n\n this.slider.selectTab(this);\n }\n\n public init(...args: any[]): Promise<any> | any {\n\n }\n\n protected onOpen() {}\n protected onOpenAfterTimeout() {}\n protected onClose() {}\n\n protected onCloseAfterTimeout() {\n if(this.destroyable) { // ! WARNING, пока что это будет работать только с самой последней внутренней вкладкой !\n this.slider?.deleteTab(this);\n this.container.remove();\n this.scrollable.destroy();\n this.listenerSetter?.removeAll();\n this.middlewareHelper?.destroy();\n }\n }\n\n protected setTitle(key: LangPackKey) {\n this.title.replaceChildren(i18n(key));\n }\n}\n\nexport class SliderSuperTabEventable extends SliderSuperTab {\n public eventListener: EventListenerBase<{\n destroy: () => void | Promise<any>,\n destroyAfter: (promise: Promise<void>) => void,\n close: () => void\n }>;\n\n constructor(slider: SidebarSlider) {\n super(slider);\n this.eventListener = new EventListenerBase();\n }\n\n onClose() {\n this.eventListener.dispatchEvent('close');\n }\n\n onCloseAfterTimeout() {\n const results = this.eventListener.dispatchResultableEvent('destroy');\n this.eventListener.dispatchEvent('destroyAfter', Promise.all(results).then(noop, noop));\n this.eventListener.cleanup();\n return super.onCloseAfterTimeout();\n }\n}\n\n/* // @ts-ignore\ninterface SliderSuperEventsTab extends SliderSuperTab, EventListenerBase<{}> {\n superConstructor: (...args: any[]) => any;\n}\nclass SliderSuperEventsTab implements SliderSuperEventsTab {\n constructor(slider: SidebarSlider) {\n this.superConstructor([slider, true]);\n }\n}\napplyMixins(SliderSuperEventsTab, [SliderSuperTab, EventListenerBase]);\n\n(window as any).lol = SliderSuperEventsTab\n\nexport {SliderSuperEventsTab}; */\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type LazyLoadQueue from './lazyLoadQueue';\nimport appDialogsManager, {AppDialogsManager, DialogDom, DialogElementSize} from '../lib/appManagers/appDialogsManager';\nimport {getHeavyAnimationPromise} from '../hooks/useHeavyAnimationCheck';\nimport isInDOM from '../helpers/dom/isInDOM';\nimport positionElementByIndex from '../helpers/dom/positionElementByIndex';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport {fastRaf} from '../helpers/schedulers';\nimport SortedList, {SortedElementBase} from '../helpers/sortedList';\nimport safeAssign from '../helpers/object/safeAssign';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport getUserStatusString from './wrappers/getUserStatusString';\nimport getChatMembersString from './wrappers/getChatMembersString';\nimport wrapParticipantRank from './wrappers/participantRank';\nimport getParticipantRank from '../lib/appManagers/utils/chats/getParticipantRank';\n\ninterface SortedUser extends SortedElementBase<PeerId> {\n dom: DialogDom\n}\n\nexport default class SortedUserList extends SortedList<SortedUser> {\n protected static SORT_INTERVAL = 30e3;\n public list: HTMLUListElement;\n public ranks: Map<PeerId, ReturnType<typeof getParticipantRank>> = new Map();\n\n protected lazyLoadQueue: LazyLoadQueue;\n protected avatarSize: DialogElementSize = 'abitbigger';\n protected rippleEnabled = true;\n protected autonomous = true;\n protected createChatListOptions: Parameters<AppDialogsManager['createChatList']>[0];\n protected onListLengthChange: () => void;\n protected getIndex: (element: SortedUser) => number;\n protected onUpdate: (element: SortedUser) => void;\n protected managers: AppManagers;\n\n constructor(options: Partial<{\n lazyLoadQueue: SortedUserList['lazyLoadQueue'],\n avatarSize: SortedUserList['avatarSize'],\n rippleEnabled: SortedUserList['rippleEnabled'],\n createChatListOptions: SortedUserList['createChatListOptions'],\n autonomous: SortedUserList['autonomous'],\n onListLengthChange: SortedUserList['onListLengthChange'],\n getIndex: SortedUserList['getIndex'],\n onUpdate: SortedUserList['onUpdate']\n }> & {\n managers: SortedUserList['managers']\n }) {\n super({\n getIndex: options.getIndex || ((element) => element.id.isAnyChat() ? 0 : this.managers.appUsersManager.getUserStatusForSort(element.id)),\n onDelete: (element) => {\n element.dom.listEl.remove();\n this.onListLengthChange && this.onListLengthChange();\n },\n onUpdate: options.onUpdate || (async(element) => {\n if(element.id.isAnyChat()) {\n const status = await getChatMembersString(element.id.toChatId(), this.managers);\n replaceContent(element.dom.lastMessageSpan, status);\n } else {\n const status = getUserStatusString(await this.managers.appUsersManager.getUser(element.id));\n replaceContent(element.dom.lastMessageSpan, status);\n }\n }),\n onSort: (element, idx) => {\n const willChangeLength = element.dom.listEl.parentElement !== this.list;\n positionElementByIndex(element.dom.listEl, this.list, idx);\n\n if(willChangeLength && this.onListLengthChange) {\n this.onListLengthChange();\n }\n },\n onElementCreate: (base) => {\n const dialogElement = appDialogsManager.addDialogNew({\n peerId: base.id,\n container: false,\n avatarSize: this.avatarSize,\n autonomous: this.autonomous,\n meAsSaved: false,\n rippleEnabled: this.rippleEnabled,\n wrapOptions: {\n lazyLoadQueue: this.lazyLoadQueue\n }\n });\n\n const rank = this.ranks.get(base.id);\n if(rank) {\n dialogElement.titleRight.replaceChildren(wrapParticipantRank(rank));\n }\n\n (base as SortedUser).dom = dialogElement.dom;\n return base as SortedUser;\n },\n updateElementWith: fastRaf,\n updateListWith: async(callback) => {\n if(!Array.from(this.elements.values()).some((element) => element.id.isUser())) {\n return callback(false);\n }\n\n if(!isInDOM(this.list)) {\n return callback(false);\n }\n\n await getHeavyAnimationPromise();\n\n if(!isInDOM(this.list)) {\n return callback(false);\n }\n\n callback(true);\n }\n });\n\n safeAssign(this, options);\n\n this.list = appDialogsManager.createChatList(this.createChatListOptions);\n\n let timeout: number;\n const doTimeout = () => {\n timeout = window.setTimeout(() => {\n this.updateList((good) => {\n if(good) {\n doTimeout();\n }\n });\n }, SortedUserList.SORT_INTERVAL);\n };\n\n doTimeout();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport AvatarElement from './avatar';\nimport type LazyLoadQueue from './lazyLoadQueue';\n\nconst CLASS_NAME = 'stacked-avatars';\nconst AVATAR_CLASS_NAME = CLASS_NAME + '-avatar';\nconst AVATAR_CONTAINER_CLASS_NAME = AVATAR_CLASS_NAME + '-container';\n\nexport default class StackedAvatars {\n public container: HTMLElement;\n private lazyLoadQueue: LazyLoadQueue;\n private avatarSize: number;\n\n constructor(options: {\n lazyLoadQueue?: StackedAvatars['lazyLoadQueue'],\n avatarSize: StackedAvatars['avatarSize']\n }) {\n this.lazyLoadQueue = options.lazyLoadQueue;\n this.avatarSize = options.avatarSize;\n\n this.container = document.createElement('div');\n this.container.classList.add(CLASS_NAME);\n\n this.container.style.setProperty('--avatar-size', options.avatarSize + 'px');\n }\n /**\n * MACOS, ANDROID - без реверса\n * WINDOWS DESKTOP - реверс\n * все приложения накладывают аватарку первую на вторую, а в макете зато вторая на первую, ЛОЛ!\n */\n public render(peerIds: PeerId[], loadPromises?: Promise<any>[]) {\n const children = this.container.children;\n peerIds = peerIds.slice().reverse();\n if(peerIds.length > 3) {\n peerIds = peerIds.slice(-3);\n }\n\n peerIds.forEach((peerId, idx) => {\n let avatarContainer = children[idx] as HTMLElement;\n if(!avatarContainer) {\n avatarContainer = document.createElement('div');\n avatarContainer.classList.add(AVATAR_CONTAINER_CLASS_NAME);\n }\n\n let avatarElem = avatarContainer.firstElementChild as AvatarElement;\n if(!avatarElem) {\n avatarElem = new AvatarElement();\n avatarElem.classList.add('avatar-' + this.avatarSize, AVATAR_CLASS_NAME);\n avatarElem.updateOptions({\n isDialog: false,\n loadPromises\n });\n }\n\n avatarElem.updateWithOptions({\n lazyLoadQueue: this.lazyLoadQueue,\n peerId: peerId\n });\n\n if(!avatarElem.parentNode) {\n avatarContainer.append(avatarElem);\n }\n\n if(!avatarContainer.parentNode) {\n this.container.append(avatarContainer);\n }\n });\n\n // if were 3 and became 2\n (Array.from(children) as HTMLElement[]).slice(peerIds.length).forEach((el) => el.remove());\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {simulateClickEvent, attachClickEvent} from '../helpers/dom/clickEvent';\nimport findUpAsChild from '../helpers/dom/findUpAsChild';\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport getVisibleRect from '../helpers/dom/getVisibleRect';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport {makeMediaSize} from '../helpers/mediaSize';\nimport {getMiddleware, Middleware} from '../helpers/middleware';\nimport {doubleRaf} from '../helpers/schedulers';\nimport pause from '../helpers/schedulers/pause';\nimport windowSize from '../helpers/windowSize';\nimport {MyDocument} from '../lib/appManagers/appDocsManager';\nimport getStickerEffectThumb from '../lib/appManagers/utils/stickers/getStickerEffectThumb';\nimport wrapEmojiText from '../lib/richTextProcessor/wrapEmojiText';\nimport {CustomEmojiElement} from '../lib/richTextProcessor/wrapRichText';\nimport lottieLoader from '../lib/rlottie/lottieLoader';\nimport RLottiePlayer from '../lib/rlottie/rlottiePlayer';\nimport rootScope from '../lib/rootScope';\nimport animationIntersector, {AnimationItemGroup} from './animationIntersector';\nimport SetTransition from './singleTransition';\nimport wrapSticker from './wrappers/sticker';\nimport {STICKER_EFFECT_MULTIPLIER} from './wrappers/sticker';\n\nlet hasViewer = false;\nexport default function attachStickerViewerListeners({listenTo, listenerSetter, selector, findTarget: originalFindTarget}: {\n listenerSetter: ListenerSetter,\n listenTo: HTMLElement,\n selector?: string,\n findTarget?: (e: MouseEvent) => HTMLElement\n}) {\n if(IS_TOUCH_SUPPORTED) {\n return;\n }\n\n const findTarget = (e: MouseEvent, checkForParent?: boolean) => {\n let el: HTMLElement;\n if(originalFindTarget) el = originalFindTarget(e);\n else {\n const s = selector || `.media-sticker-wrapper`;\n el = (e.target as HTMLElement).closest(s) as HTMLElement;\n }\n\n return el && (!checkForParent || findUpAsChild(el, listenTo)) ? el : undefined;\n };\n\n const managers = rootScope.managers;\n\n listenerSetter.add(listenTo)('mousedown', (e) => {\n if(hasViewer || e.buttons > 1 || e.button !== 0) return;\n let mediaContainer = findTarget(e);\n if(!mediaContainer) {\n return;\n }\n\n // const img: HTMLImageElement = mediaContainer.querySelector('img.media-sticker');\n\n const docId = mediaContainer.dataset.docId;\n if(!docId) {\n return;\n }\n\n const className = 'sticker-viewer';\n const group: AnimationItemGroup = 'STICKER-VIEWER';\n const openDuration = 200;\n const switchDuration = 200;\n const previousGroup = animationIntersector.getOnlyOnePlayableGroup();\n const _middleware = getMiddleware();\n let container: HTMLElement, previousTransformer: HTMLElement;\n\n const doThatSticker = async({mediaContainer, doc, middleware, lockGroups, isSwitching}: {\n mediaContainer: HTMLElement,\n doc: MyDocument,\n middleware: Middleware,\n lockGroups?: boolean,\n isSwitching?: boolean\n }) => {\n const effectThumb = getStickerEffectThumb(doc);\n const mediaRect: DOMRect = mediaContainer.getBoundingClientRect();\n const s = makeMediaSize(doc.w, doc.h);\n const size = effectThumb ? 280 : 360;\n const boxSize = makeMediaSize(size, size);\n const fitted = mediaRect.width === mediaRect.height ? boxSize : s.aspectFitted(boxSize);\n\n const bubble = findUpClassName(mediaContainer, 'bubble');\n const isOut = bubble ? bubble.classList.contains('is-out') : true;\n\n const transformer = document.createElement('div');\n transformer.classList.add(className + '-transformer');\n\n const stickerContainer = document.createElement('div');\n stickerContainer.classList.add(className + '-sticker');\n /* transformer.style.width = */stickerContainer.style.width = fitted.width + 'px';\n /* transformer.style.height = */stickerContainer.style.height = fitted.height + 'px';\n\n const stickerEmoji = document.createElement('div');\n stickerEmoji.classList.add(className + '-emoji');\n stickerEmoji.append(wrapEmojiText(doc.stickerEmojiRaw));\n\n if(effectThumb) {\n const margin = (size * STICKER_EFFECT_MULTIPLIER - size) / 3 * (isOut ? 1 : -1);\n transformer.classList.add('has-effect');\n // const property = `--margin-${isOut ? 'right' : 'left'}`;\n // stickerContainer.style.setProperty(property, `${margin * 2}px`);\n transformer.style.setProperty('--translateX', `${margin}px`);\n stickerEmoji.style.setProperty('--translateX', `${-margin}px`);\n }\n\n const overflowElement = findUpClassName(mediaContainer, 'scrollable');\n const visibleRect = getVisibleRect(mediaContainer, overflowElement, true, mediaRect);\n if(visibleRect.overflow.vertical || visibleRect.overflow.horizontal) {\n stickerContainer.classList.add('is-overflow');\n }\n\n // if(img) {\n // const ratio = img.naturalWidth / img.naturalHeight;\n // if((mediaRect.width / mediaRect.height).toFixed(1) !== ratio.toFixed(1)) {\n\n // mediaRect = mediaRect.toJSON();\n // }\n // }\n\n const rect = mediaContainer.getBoundingClientRect();\n const scaleX = rect.width / fitted.width;\n const scaleY = rect.height / fitted.height;\n const transformX = rect.left - (windowSize.width - rect.width) / 2;\n const transformY = rect.top - (windowSize.height - rect.height) / 2;\n transformer.style.transform = `translate(${transformX}px, ${transformY}px) scale(${scaleX}, ${scaleY})`;\n if(isSwitching) transformer.classList.add('is-switching');\n transformer.append(stickerContainer, stickerEmoji);\n container.append(transformer);\n\n const o = await wrapSticker({\n doc,\n div: stickerContainer,\n group,\n width: fitted.width,\n height: fitted.height,\n play: false,\n loop: true,\n middleware,\n managers,\n needFadeIn: false,\n isOut,\n withThumb: false,\n relativeEffect: true,\n loopEffect: true\n }).then(({render}) => render);\n if(!middleware()) return;\n\n if(!container.parentElement) {\n document.body.append(container);\n }\n\n const player = Array.isArray(o) ? o[0] : o;\n\n const firstFramePromise = player instanceof RLottiePlayer ?\n new Promise<void>((resolve) => player.addEventListener('firstFrame', resolve, {once: true})) :\n Promise.resolve();\n await Promise.all([firstFramePromise, doubleRaf()]);\n await pause(0); // ! need it because firstFrame will be called just from the loop\n if(!middleware()) return;\n\n if(lockGroups) {\n animationIntersector.setOnlyOnePlayableGroup(group);\n animationIntersector.checkAnimations2(true);\n }\n\n if(player instanceof RLottiePlayer) {\n const prevPlayer = mediaContainer instanceof CustomEmojiElement ?\n mediaContainer.player as RLottiePlayer :\n lottieLoader.getAnimation(mediaContainer);\n if(prevPlayer) {\n player.curFrame = prevPlayer.curFrame;\n player.play();\n await new Promise<void>((resolve) => {\n let i = 0;\n const c = () => {\n if(++i === 2) {\n resolve();\n player.removeEventListener('enterFrame', c);\n }\n };\n\n player.addEventListener('enterFrame', c);\n });\n if(!middleware()) return;\n player.pause();\n }\n } else if(player instanceof HTMLVideoElement) {\n const prevPlayer = mediaContainer.querySelector<HTMLVideoElement>('video');\n if(prevPlayer) {\n player.currentTime = prevPlayer.currentTime;\n }\n }\n\n return {\n ready: () => {\n if(player instanceof RLottiePlayer || player instanceof HTMLVideoElement) {\n player.play();\n }\n\n if(effectThumb) {\n simulateClickEvent(stickerContainer);\n }\n },\n transformer\n };\n };\n\n const timeout = window.setTimeout(async() => {\n document.removeEventListener('mousemove', onMousePreMove);\n\n container = document.createElement('div');\n container.classList.add(className);\n hasViewer = true;\n\n const middleware = _middleware.get();\n const doc = await managers.appDocsManager.getDoc(docId);\n if(!middleware()) return;\n\n let result: Awaited<ReturnType<typeof doThatSticker>>;\n try {\n result = await doThatSticker({\n doc,\n mediaContainer,\n middleware,\n lockGroups: true\n });\n if(!result) return;\n } catch(err) {\n return;\n }\n\n const {ready, transformer} = result;\n\n previousTransformer = transformer;\n\n SetTransition({\n element: container,\n className: 'is-visible',\n forwards: true,\n duration: openDuration,\n onTransitionEnd: () => {\n if(!middleware()) return;\n ready();\n }\n });\n\n document.addEventListener('mousemove', onMouseMove);\n }, 125);\n\n const onMouseMove = async(e: MouseEvent) => {\n const newMediaContainer = findTarget(e, true);\n if(!newMediaContainer || mediaContainer === newMediaContainer) {\n return;\n }\n\n const docId = newMediaContainer.dataset.docId;\n if(!docId) {\n return;\n }\n\n mediaContainer = newMediaContainer;\n _middleware.clean();\n const middleware = _middleware.get();\n\n const doc = await managers.appDocsManager.getDoc(docId);\n if(!middleware()) return;\n\n let r: Awaited<ReturnType<typeof doThatSticker>>;\n try {\n r = await doThatSticker({\n doc,\n mediaContainer,\n middleware,\n isSwitching: true\n });\n if(!r) return;\n } catch(err) {\n console.error('sticker viewer error', err);\n return;\n }\n\n const {ready, transformer} = r;\n\n const _previousTransformer = previousTransformer;\n SetTransition({\n element: _previousTransformer,\n className: 'is-switching',\n forwards: true,\n duration: switchDuration,\n onTransitionEnd: () => {\n _previousTransformer.remove();\n }\n });\n\n previousTransformer = transformer;\n\n SetTransition({\n element: transformer,\n className: 'is-switching',\n forwards: false,\n duration: switchDuration,\n onTransitionEnd: () => {\n if(!middleware()) return;\n ready();\n }\n });\n };\n\n const onMousePreMove = (e: MouseEvent) => {\n if(!findUpAsChild(e.target as HTMLElement, mediaContainer)) {\n onMouseUp();\n }\n };\n\n const onMouseUp = () => {\n clearTimeout(timeout);\n _middleware.clean();\n\n if(container) {\n SetTransition({\n element: container,\n className: 'is-visible',\n forwards: false,\n duration: openDuration,\n onTransitionEnd: () => {\n container.remove();\n animationIntersector.setOnlyOnePlayableGroup(previousGroup);\n animationIntersector.checkAnimations2(false);\n hasViewer = false;\n }\n });\n\n attachClickEvent(document.body, cancelEvent, {capture: true, once: true});\n }\n\n document.removeEventListener('mousemove', onMousePreMove);\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp, {capture: true});\n };\n\n document.addEventListener('mousemove', onMousePreMove);\n document.addEventListener('mouseup', onMouseUp, {once: true, capture: true});\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default class StickyIntersector {\n private headersObserver: IntersectionObserver;\n private elementsObserver: IntersectionObserver;\n\n constructor(private container: HTMLElement, private handler: (stuck: boolean, target: HTMLElement) => void) {\n this.observeHeaders();\n this.observeElements();\n }\n\n /**\n * Sets up an intersection observer to notify when elements with the class\n * `.sticky_sentinel--top` become visible/invisible at the top of the container.\n * @param {!Element} container\n */\n private observeHeaders() {\n this.headersObserver = new IntersectionObserver((entries) => {\n for(const entry of entries) {\n const targetInfo = entry.boundingClientRect;\n const stickyTarget = entry.target.parentElement;\n const rootBoundsInfo = entry.rootBounds;\n\n // Started sticking.\n if(targetInfo.bottom < rootBoundsInfo.top) {\n this.handler(true, stickyTarget);\n }\n\n // Stopped sticking.\n if(targetInfo.bottom >= rootBoundsInfo.top &&\n targetInfo.bottom < rootBoundsInfo.bottom) {\n this.handler(false, stickyTarget);\n }\n }\n }, {threshold: 0, root: this.container});\n }\n\n private observeElements() {\n this.elementsObserver = new IntersectionObserver((entries) => {\n const entry = entries\n .filter((entry) => entry.boundingClientRect.top < entry.rootBounds.top)\n .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top)[0];\n if(!entry) return;\n\n const container = entry.isIntersecting ? entry.target : entry.target.nextElementSibling;\n this.handler(true, container as HTMLElement);\n }, {root: this.container});\n }\n\n /**\n * @param {!Element} container\n * @param {string} className\n */\n private addSentinel(container: HTMLElement, className: string) {\n const sentinel = document.createElement('div');\n sentinel.classList.add('sticky_sentinel', className);\n return container.appendChild(sentinel);\n }\n\n /**\n * Notifies when elements w/ the `sticky` class begin to stick or stop sticking.\n * Note: the elements should be children of `container`.\n * @param {!Element} container\n */\n public observeStickyHeaderChanges(element: HTMLElement) {\n const headerSentinel = this.addSentinel(element, 'sticky_sentinel--top');\n this.headersObserver.observe(headerSentinel);\n\n this.elementsObserver.observe(element);\n }\n\n public disconnect() {\n this.headersObserver.disconnect();\n this.elementsObserver.disconnect();\n }\n\n public unobserve(element: HTMLElement, headerSentinel: HTMLElement) {\n this.elementsObserver.unobserve(element);\n this.headersObserver.unobserve(headerSentinel);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// * zoom part from WebZ\n// * https://github.com/Ajaxy/telegram-tt/blob/069f4f5b2f2c7c22529ccced876842e7f9cb81f4/src/util/captureEvents.ts\n\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport safeAssign from '../helpers/object/safeAssign';\nimport contextMenuController from '../helpers/contextMenuController';\nimport {Middleware} from '../helpers/middleware';\nimport ListenerSetter, {Listener, ListenerOptions} from '../helpers/listenerSetter';\nimport {attachContextMenuListener} from '../helpers/dom/attachContextMenuListener';\nimport pause from '../helpers/schedulers/pause';\nimport deferredPromise from '../helpers/cancellablePromise';\nimport clamp from '../helpers/number/clamp';\nimport debounce from '../helpers/schedulers/debounce';\nimport {logger} from '../lib/logger';\nimport isSwipingBackSafari from '../helpers/dom/isSwipingBackSafari';\nimport windowSize from '../helpers/windowSize';\n\ntype E = {\n clientX: number,\n clientY: number,\n target: EventTarget,\n button?: number,\n type?: string\n};\n\ntype EE = E | (Exclude<E, 'clientX' | 'clientY'> & {\n touches: E[]\n});\n\nconst getEvent = (e: EE) => {\n return 'touches' in e ? e.touches[0] : e;\n};\n\nfunction getDistance(a: Touch, b?: Touch) {\n if(!b) return 0;\n return Math.hypot((b.pageX - a.pageX), (b.pageY - a.pageY));\n}\n\nfunction getTouchCenter(a: Touch, b: Touch) {\n return {\n x: (a.pageX + b.pageX) / 2,\n y: (a.pageY + b.pageY) / 2\n };\n}\n\nconst attachGlobalListenerTo = document;\n\nlet RESET_GLOBAL = false;\ncontextMenuController.addEventListener('toggle', (visible) => {\n RESET_GLOBAL = visible;\n});\n\nexport type SwipeHandlerOptions = {\n element: SwipeHandler['element'],\n onSwipe: SwipeHandler['onSwipe'],\n verifyTouchTarget?: SwipeHandler['verifyTouchTarget'],\n onFirstSwipe?: SwipeHandler['onFirstSwipe'],\n onReset?: SwipeHandler['onReset'],\n onStart?: SwipeHandler['onStart'],\n onZoom?: SwipeHandler['onZoom'],\n onDrag?: SwipeHandler['onDrag'],\n onDoubleClick?: SwipeHandler['onDoubleClick'],\n cursor?: SwipeHandler['cursor'],\n cancelEvent?: SwipeHandler['cancelEvent'],\n listenerOptions?: SwipeHandler['listenerOptions'],\n setCursorTo?: HTMLElement,\n middleware?: Middleware,\n withDelay?: boolean,\n minZoom?: number,\n maxZoom?: number\n};\n\nconst TOUCH_MOVE_OPTIONS: ListenerOptions = {passive: false};\nconst MOUSE_MOVE_OPTIONS: ListenerOptions = false as any;\nconst WHEEL_OPTIONS: ListenerOptions = {capture: true, passive: false};\n\nexport type ZoomDetails = {\n zoom?: number;\n zoomFactor?: number;\n zoomAdd?: number;\n initialCenterX: number;\n initialCenterY: number;\n dragOffsetX: number;\n dragOffsetY: number;\n currentCenterX: number;\n currentCenterY: number;\n};\n\nexport default class SwipeHandler {\n private element: HTMLElement;\n private onSwipe: (xDiff: number, yDiff: number, e: EE, cancelDrag?: (x: boolean, y: boolean) => void) => boolean | void;\n private verifyTouchTarget: (evt: EE) => boolean | Promise<boolean>;\n private onFirstSwipe: (e: EE) => void;\n private onReset: (e?: Event) => void;\n private onStart: () => void;\n private onZoom: (details: ZoomDetails) => void;\n private onDrag: (e: EE, captureEvent: E, details: {dragOffsetX: number, dragOffsetY: number}, cancelDrag: (x: boolean, y: boolean) => void) => void;\n private onDoubleClick: (details: {centerX: number, centerY: number}) => void;\n private cursor: 'grabbing' | 'move' | 'row-resize' | 'col-resize' | 'nesw-resize' | 'nwse-resize' | 'ne-resize' | 'se-resize' | 'sw-resize' | 'nw-resize' | 'n-resize' | 'e-resize' | 's-resize' | 'w-resize' | '';\n private cancelEvent: boolean;\n private listenerOptions: ListenerOptions;\n private setCursorTo: HTMLElement;\n\n private isMouseDown: boolean;\n private tempId: number;\n\n private hadMove: boolean;\n private eventUp: E;\n private xDown: number;\n private yDown: number;\n private xAdded: number;\n private yAdded: number;\n\n private withDelay: boolean;\n private listenerSetter: ListenerSetter;\n\n private initialDistance: number;\n private initialTouchCenter: ReturnType<typeof getTouchCenter>;\n private initialDragOffset: {x: number, y: number};\n private isDragCanceled: {x: boolean, y: boolean};\n private wheelZoom: number;\n private releaseWheelDrag: ReturnType<typeof debounce<(e: Event) => void>>;\n private releaseWheelZoom: ReturnType<typeof debounce<(e: Event) => void>>;\n\n private log: ReturnType<typeof logger>;\n\n constructor(options: SwipeHandlerOptions) {\n safeAssign(this, options);\n\n this.log = logger('SWIPE-HANDLER');\n this.cursor ??= 'grabbing';\n this.cancelEvent ??= true;\n // this.listenerOptions ??= false as any;\n this.listenerOptions ??= TOUCH_MOVE_OPTIONS;\n\n this.setCursorTo ??= this.element;\n this.listenerSetter = new ListenerSetter();\n this.setListeners();\n\n this.resetValues();\n this.tempId = 0;\n\n options.middleware?.onDestroy(() => {\n this.reset();\n this.removeListeners();\n });\n\n this.releaseWheelDrag = debounce(this.reset, 150, false);\n this.releaseWheelZoom = debounce(this.reset, 150, false);\n }\n\n public setListeners() {\n if(!IS_TOUCH_SUPPORTED) {\n // @ts-ignore\n this.listenerSetter.add(this.element)('mousedown', this.handleStart, this.listenerOptions);\n this.listenerSetter.add(attachGlobalListenerTo)('mouseup', this.reset);\n\n if(this.onZoom || this.onDoubleClick) {\n this.listenerSetter.add(this.element)('wheel', this.handleWheel, WHEEL_OPTIONS);\n }\n } else {\n if(this.withDelay) {\n attachContextMenuListener({\n element: this.element,\n callback: (e) => {\n cancelEvent(e);\n // @ts-ignore\n this.handleStart(e);\n },\n listenerSetter: this.listenerSetter,\n listenerOptions: this.listenerOptions\n });\n } else {\n // @ts-ignore\n this.listenerSetter.add(this.element)('touchstart', this.handleStart, this.listenerOptions);\n }\n\n if(this.onDoubleClick) {\n this.listenerSetter.add(this.element)('dblclick', (e) => {\n this.onDoubleClick({centerX: e.pageX, centerY: e.pageY});\n });\n }\n\n this.listenerSetter.add(attachGlobalListenerTo)('touchend', this.reset);\n }\n }\n\n public removeListeners() {\n this.log('remove listeners');\n this.reset();\n this.listenerSetter.removeAll();\n }\n\n public setCursor(cursor: SwipeHandler['cursor'] = '') {\n this.cursor = cursor;\n\n if(!IS_TOUCH_SUPPORTED && this.hadMove) {\n this.setCursorTo.style.setProperty('cursor', this.cursor, 'important');\n }\n }\n\n public add(x: number, y: number) {\n this.xAdded = x;\n this.yAdded = y;\n this.handleMove({\n clientX: this.eventUp.clientX,\n clientY: this.eventUp.clientY,\n target: this.eventUp.target\n });\n }\n\n protected resetValues() {\n ++this.tempId;\n this.hadMove = false;\n this.xAdded = this.yAdded = 0;\n this.xDown =\n this.yDown =\n this.eventUp =\n this.isMouseDown =\n undefined;\n\n if(this.onZoom) {\n this.initialDistance = 0;\n this.initialTouchCenter = {\n x: windowSize.width / 2,\n y: windowSize.height / 2\n };\n this.initialDragOffset = {x: 0, y: 0};\n this.isDragCanceled = {x: false, y: false};\n this.wheelZoom = 1;\n }\n }\n\n protected reset = (e?: Event) => {\n this.log('reset');\n /* if(e) {\n cancelEvent(e);\n } */\n\n if(IS_TOUCH_SUPPORTED) {\n this.listenerSetter.removeManual(attachGlobalListenerTo, 'touchmove', this.handleMove, TOUCH_MOVE_OPTIONS);\n } else {\n this.listenerSetter.removeManual(attachGlobalListenerTo, 'mousemove', this.handleMove, MOUSE_MOVE_OPTIONS);\n this.setCursorTo.style.cursor = '';\n }\n\n if(this.hadMove) {\n this.onReset?.(e);\n }\n\n this.releaseWheelDrag?.clearTimeout();\n this.releaseWheelZoom?.clearTimeout();\n\n this.resetValues();\n };\n\n protected setHadMove(_e: EE) {\n if(!this.hadMove) {\n this.log('had move');\n this.hadMove = true;\n this.setCursorTo.style.setProperty('cursor', this.cursor, 'important');\n this.onFirstSwipe?.(_e);\n }\n }\n\n protected dispatchOnSwipe(...args: Parameters<SwipeHandlerOptions['onSwipe']>) {\n const onSwipeResult = this.onSwipe(...args);\n if(onSwipeResult !== undefined && onSwipeResult) {\n this.reset();\n }\n }\n\n protected handleStart = async(_e: EE) => {\n this.log('start');\n\n if(this.isMouseDown) {\n const touches = (_e as any as TouchEvent).touches;\n if(touches?.length === 2) {\n this.initialDistance = getDistance(touches[0], touches[1]);\n this.initialTouchCenter = getTouchCenter(touches[0], touches[1]);\n }\n\n return;\n }\n\n const e = getEvent(_e);\n if(![0, 1].includes(Math.max(0, e.button ?? 0))) {\n return;\n }\n\n if(e.button === 1) {\n cancelEvent(_e as any);\n }\n\n if(isSwipingBackSafari(_e as any)) {\n return;\n }\n\n const tempId = ++this.tempId;\n\n const verifyResult = this.verifyTouchTarget?.(_e);\n if(verifyResult !== undefined) {\n let result: any;\n if(verifyResult instanceof Promise) {\n // const tempId = this.tempId;\n result = await verifyResult;\n\n if(this.tempId !== tempId) {\n return;\n }\n } else {\n result = verifyResult;\n }\n\n if(!result) {\n return this.reset();\n }\n }\n\n this.isMouseDown = true;\n\n if(this.withDelay && !IS_TOUCH_SUPPORTED) {\n const options = {...MOUSE_MOVE_OPTIONS, once: true};\n const deferred = deferredPromise<void>();\n const cb = () => deferred.resolve();\n const listener = this.listenerSetter.add(attachGlobalListenerTo)('mousemove', cb, options) as any as Listener;\n\n await Promise.race([\n pause(300),\n deferred\n ]);\n\n deferred.resolve();\n this.listenerSetter.remove(listener);\n\n if(this.tempId !== tempId) {\n return;\n }\n }\n\n this.xDown = e.clientX;\n this.yDown = e.clientY;\n this.eventUp = e;\n\n if(IS_TOUCH_SUPPORTED) {\n // @ts-ignore\n this.listenerSetter.add(attachGlobalListenerTo)('touchmove', this.handleMove, TOUCH_MOVE_OPTIONS);\n } else {\n // @ts-ignore\n this.listenerSetter.add(attachGlobalListenerTo)('mousemove', this.handleMove, MOUSE_MOVE_OPTIONS);\n }\n\n if(this.onStart) {\n this.onStart();\n\n // have to initiate move instantly\n this.hadMove = true;\n this.handleMove(e);\n }\n };\n\n protected handleMove = (_e: EE) => {\n if(this.xDown === undefined || this.yDown === undefined || RESET_GLOBAL) {\n this.reset();\n return;\n }\n\n if(this.cancelEvent) {\n cancelEvent(_e as any);\n }\n\n if(this.releaseWheelDrag?.isDebounced() || this.releaseWheelZoom?.isDebounced()) {\n return;\n }\n\n this.log('move');\n\n const e = this.eventUp = getEvent(_e);\n const xUp = e.clientX;\n const yUp = e.clientY;\n\n const xDiff = xUp - this.xDown + this.xAdded;\n const yDiff = yUp - this.yDown + this.yAdded;\n\n if(!this.hadMove) {\n if(!xDiff && !yDiff) {\n return;\n }\n\n this.setHadMove(_e);\n }\n\n const touches = (_e as any as TouchEvent).touches;\n if(this.onZoom && this.initialDistance > 0 && touches.length === 2) {\n const endDistance = getDistance(touches[0], touches[1]);\n const touchCenter = getTouchCenter(touches[0], touches[1]);\n const dragOffsetX = touchCenter.x - this.initialTouchCenter.x;\n const dragOffsetY = touchCenter.y - this.initialTouchCenter.y;\n const zoomFactor = endDistance / this.initialDistance;\n const details: ZoomDetails = {\n zoomFactor,\n initialCenterX: this.initialTouchCenter.x,\n initialCenterY: this.initialTouchCenter.y,\n dragOffsetX,\n dragOffsetY,\n currentCenterX: touchCenter.x,\n currentCenterY: touchCenter.y\n };\n\n this.onZoom(details);\n }\n\n this.dispatchOnSwipe(xDiff, yDiff, _e);\n };\n\n protected handleWheel = (e: WheelEvent) => {\n if(!this.hadMove && this.verifyTouchTarget) {\n const result = this.verifyTouchTarget(e);\n if(result !== undefined && !result) {\n this.reset(e);\n return;\n }\n }\n\n cancelEvent(e);\n\n this.log('wheel');\n\n if(this.onDoubleClick && Object.is(e.deltaX, -0) && Object.is(e.deltaY, -0) && e.ctrlKey) {\n this.onWheelCapture(e);\n this.onDoubleClick({centerX: e.pageX, centerY: e.pageY});\n this.reset();\n return;\n }\n\n const metaKeyPressed = e.metaKey || e.ctrlKey || e.shiftKey;\n if(metaKeyPressed) {\n // * fix zooming while dragging is in inertia\n if(this.releaseWheelDrag?.isDebounced()) {\n this.reset();\n }\n\n this.onWheelZoom(e);\n } else {\n this.handleWheelDrag(e);\n }\n };\n\n protected handleWheelDrag = (e: WheelEvent) => {\n this.log('wheel drag');\n\n this.onWheelCapture(e);\n // Ignore wheel inertia if drag is canceled in this direction\n if(!this.isDragCanceled.x || Math.sign(this.initialDragOffset.x) === Math.sign(e.deltaX)) {\n this.initialDragOffset.x -= e.deltaX;\n }\n if(!this.isDragCanceled.y || Math.sign(this.initialDragOffset.y) === Math.sign(e.deltaY)) {\n this.initialDragOffset.y -= e.deltaY;\n }\n const {x, y} = this.initialDragOffset;\n this.releaseWheelDrag(e);\n this.dispatchOnSwipe(x, y, e, (dx, dy) => {\n this.isDragCanceled = {x: dx, y: dy};\n });\n };\n\n protected onWheelCapture = (e: WheelEvent) => {\n if(this.hadMove) return;\n this.log('wheel capture');\n this.handleStart(e);\n this.setHadMove(e);\n this.initialTouchCenter = {x: e.x, y: e.y};\n };\n\n protected onWheelZoom = (e: WheelEvent) => {\n if(!this.onZoom) return;\n this.log('wheel zoom');\n this.onWheelCapture(e);\n const dragOffsetX = e.x - this.initialTouchCenter.x;\n const dragOffsetY = e.y - this.initialTouchCenter.y;\n const delta = clamp(e.deltaY, -25, 25);\n this.wheelZoom -= delta * 0.01;\n const details: ZoomDetails = {\n zoomAdd: this.wheelZoom - 1,\n initialCenterX: this.initialTouchCenter.x,\n initialCenterY: this.initialTouchCenter.y,\n dragOffsetX,\n dragOffsetY,\n currentCenterX: e.x,\n currentCenterY: e.y\n };\n this.onZoom(details);\n this.releaseWheelZoom(e);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport placeCaretAtEnd from '../helpers/dom/placeCaretAtEnd';\nimport {formatPhoneNumber} from '../helpers/formatPhoneNumber';\nimport {IS_APPLE, IS_ANDROID, IS_APPLE_MOBILE} from '../environment/userAgent';\nimport {HelpCountry, HelpCountryCode} from '../layer';\nimport InputField, {InputFieldOptions} from './inputField';\n\nexport default class TelInputField extends InputField {\n private pasted = false;\n public lastValue = '';\n\n constructor(options: InputFieldOptions & {\n onInput?: (formatted: ReturnType<typeof formatPhoneNumber>) => void\n } = {}) {\n super({\n label: 'Contacts.PhoneNumber.Placeholder',\n // plainText: true,\n name: 'phone',\n ...options\n });\n\n this.container.classList.add('input-field-phone');\n\n const telEl = this.input;\n if(telEl instanceof HTMLInputElement) {\n telEl.type = 'tel';\n telEl.autocomplete = 'rr55RandomRR55';\n } else {\n telEl.inputMode = 'decimal';\n\n const pixelRatio = window.devicePixelRatio;\n if(pixelRatio > 1) {\n let letterSpacing: number;\n if(IS_APPLE) {\n letterSpacing = pixelRatio * -.16;\n } else if(IS_ANDROID) {\n letterSpacing = 0;\n }\n\n telEl.style.setProperty('--letter-spacing', letterSpacing + 'px');\n }\n\n const originalFunc = this.setValueSilently.bind(this);\n this.setValueSilently = (value) => {\n originalFunc(value);\n placeCaretAtEnd(this.input, true);\n };\n }\n\n telEl.addEventListener('input', () => {\n // console.log('input', this.value);\n telEl.classList.remove('error');\n\n const value = this.value;\n const diff = Math.abs(value.length - this.lastValue.length);\n if(diff > 1 && !this.pasted && IS_APPLE_MOBILE) {\n this.setValueSilently(this.lastValue + value);\n }\n\n this.pasted = false;\n\n this.setLabel();\n\n let formattedPhoneNumber: ReturnType<typeof formatPhoneNumber>;\n let formatted: string, country: HelpCountry, countryCode: HelpCountryCode, leftPattern = '';\n if(this.value.replace(/\\++/, '+') === '+') {\n this.setValueSilently('+');\n } else {\n formattedPhoneNumber = formatPhoneNumber(this.value);\n formatted = formattedPhoneNumber.formatted;\n country = formattedPhoneNumber.country;\n leftPattern = formattedPhoneNumber.leftPattern;\n countryCode = formattedPhoneNumber.code;\n this.setValueSilently(this.lastValue = formatted ? '+' + formatted : '');\n }\n\n telEl.dataset.leftPattern = leftPattern/* .replace(/X/g, '0') */;\n\n // console.log(formatted, country);\n\n options.onInput && options.onInput(formattedPhoneNumber);\n });\n\n telEl.addEventListener('paste', () => {\n this.pasted = true;\n // console.log('paste', telEl.value);\n });\n\n /* telEl.addEventListener('change', (e) => {\n console.log('change', telEl.value);\n }); */\n\n telEl.addEventListener('keypress', (e) => {\n // console.log('keypress', this.value);\n const key = e.key;\n if(/\\D/.test(key) && !(e.metaKey || e.ctrlKey) && key !== 'Backspace' && !(key === '+' && e.shiftKey/* && !this.value */)) {\n e.preventDefault();\n return false;\n }\n });\n\n /* telEl.addEventListener('focus', function(this: typeof telEl, e) {\n this.removeAttribute('readonly'); // fix autocomplete\n });*/\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport EventListenerBase from '../helpers/eventListenerBase';\nimport {TelegramWebViewEvent, TelegramWebViewEventCallback, TelegramWebViewEventMap} from '../types';\n\nconst weakMap: WeakMap<Window, TelegramWebViewEventCallback> = new WeakMap();\nwindow.addEventListener('message', (e) => {\n const callback = weakMap.get(e.source as Window);\n if(!callback) {\n return;\n }\n\n callback(JSON.parse(e.data));\n});\n\nexport default class TelegramWebView extends EventListenerBase<{\n [type in keyof TelegramWebViewEventMap]: (data: TelegramWebViewEventMap[type]) => void\n}> {\n public iframe: HTMLIFrameElement;\n\n constructor({url, sandbox}: {\n url: string,\n sandbox?: string\n }) {\n super(false);\n\n const iframe = this.iframe = document.createElement('iframe');\n iframe.src = url;\n if(sandbox) iframe.setAttribute('sandbox', sandbox);\n }\n\n public onMount() {\n weakMap.set(this.iframe.contentWindow, this.onTelegramWebViewEvent);\n }\n\n public destroy() {\n this.cleanup();\n weakMap.delete(this.iframe.contentWindow);\n }\n\n private onTelegramWebViewEvent = ({eventType, eventData}: TelegramWebViewEvent) => {\n if((eventData as any) === '') {\n eventData = undefined;\n }\n\n console.log('onTelegramWebViewEvent', eventType, eventData);\n this.dispatchEvent(eventType, eventData as any);\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport replaceContent from '../helpers/dom/replaceContent';\nimport OverlayClickHandler from '../helpers/overlayClickHandler';\nimport {FormatterArguments, i18n, LangPackKey} from '../lib/langPack';\n\nconst toastEl = document.createElement('div');\ntoastEl.classList.add('toast');\nlet timeout: number;\n\nconst x = new OverlayClickHandler('toast');\nx.addEventListener('toggle', (open) => {\n if(!open) {\n hideToast();\n }\n});\n\nexport function hideToast() {\n x.close();\n\n toastEl.classList.remove('is-visible');\n timeout && clearTimeout(+timeout);\n\n timeout = window.setTimeout(() => {\n toastEl.remove();\n timeout = undefined;\n }, 200);\n}\n\nexport function toast(content: string | Node, onClose?: () => void) {\n x.close();\n\n replaceContent(toastEl, content);\n\n if(!toastEl.parentElement) {\n document.body.append(toastEl);\n void toastEl.offsetLeft; // reflow\n }\n\n toastEl.classList.add('is-visible');\n\n timeout && clearTimeout(+timeout);\n x.open(toastEl);\n\n timeout = window.setTimeout(hideToast, 3000);\n\n if(onClose) {\n x.addEventListener('toggle', onClose, {once: true});\n }\n}\n\nexport function toastNew(options: Partial<{\n langPackKey: LangPackKey,\n langPackArguments: FormatterArguments,\n onClose: () => void\n}>) {\n toast(i18n(options.langPackKey, options.langPackArguments), options.onClose);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport rootScope from '../lib/rootScope';\nimport deferredPromise, {CancellablePromise} from '../helpers/cancellablePromise';\nimport {dispatchHeavyAnimationEvent} from '../hooks/useHeavyAnimationCheck';\nimport whichChild from '../helpers/dom/whichChild';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport liteMode from '../helpers/liteMode';\n\nfunction makeTransitionFunction(options: TransitionFunction) {\n return options;\n}\n\nconst slideNavigation = makeTransitionFunction({\n callback: (tabContent, prevTabContent, toRight) => {\n const width = prevTabContent.getBoundingClientRect().width;\n const elements = [tabContent, prevTabContent];\n if(toRight) elements.reverse();\n elements[0].style.filter = `brightness(80%)`;\n elements[0].style.transform = `translate3d(${-width * .25}px, 0, 0)`;\n elements[1].style.transform = `translate3d(${width}px, 0, 0)`;\n\n tabContent.classList.add('active');\n void tabContent.offsetWidth; // reflow\n\n tabContent.style.transform = '';\n tabContent.style.filter = '';\n\n return () => {\n prevTabContent.style.transform = prevTabContent.style.filter = '';\n };\n },\n animateFirst: false\n});\n\nconst slideTabs = makeTransitionFunction({\n callback: (tabContent, prevTabContent, toRight) => {\n // Jolly Cobra's // Workaround for scrollable content flickering during animation.\n // const scrollableContainer = findUpClassName(tabContent, 'scrollable-y');\n // if(scrollableContainer && scrollableContainer.style.overflowY !== 'hidden') {\n // // const scrollBarWidth = scrollableContainer.offsetWidth - scrollableContainer.clientWidth;\n // scrollableContainer.style.overflowY = 'hidden';\n // // scrollableContainer.style.paddingRight = `${scrollBarWidth}px`;\n // // this.container.classList.add('sliding');\n // }\n\n // window.requestAnimationFrame(() => {\n const width = prevTabContent.getBoundingClientRect().width;\n /* tabContent.style.setProperty('--width', width + 'px');\n prevTabContent.style.setProperty('--width', width + 'px');\n\n tabContent.classList.add('active'); */\n // void tabContent.offsetWidth; // reflow\n const elements = [tabContent, prevTabContent];\n if(toRight) elements.reverse();\n elements[0].style.transform = `translate3d(${-width}px, 0, 0)`;\n elements[1].style.transform = `translate3d(${width}px, 0, 0)`;\n\n tabContent.classList.add('active');\n void tabContent.offsetWidth; // reflow\n\n tabContent.style.transform = '';\n // });\n\n return () => {\n prevTabContent.style.transform = '';\n\n // if(scrollableContainer) {\n // // Jolly Cobra's // Workaround for scrollable content flickering during animation.\n // if(isSafari) { // ! safari doesn't respect sticky header, so it flicks when overflow is changing\n // scrollableContainer.style.display = 'none';\n // }\n\n // scrollableContainer.style.overflowY = '';\n\n // if(isSafari) {\n // void scrollableContainer.offsetLeft; // reflow\n // scrollableContainer.style.display = '';\n // }\n\n // // scrollableContainer.style.paddingRight = '0';\n // // this.container.classList.remove('sliding');\n // }\n };\n },\n animateFirst: false\n});\n\nconst slideTopics = makeTransitionFunction({\n callback: (tabContent, prevTabContent) => {\n const rect = tabContent.getBoundingClientRect();\n const offsetX = rect.width - 80;\n\n tabContent.style.transform = `transformX(${offsetX}px)`;\n\n tabContent.classList.add('active');\n void tabContent.offsetWidth; // reflow\n\n tabContent.style.transform = '';\n\n return () => {};\n },\n animateFirst: true\n});\n\nconst transitions: {[type in TransitionSliderType]?: TransitionFunction} = {\n navigation: slideNavigation,\n tabs: slideTabs\n // topics: slideTopics\n};\n\ntype TransitionSliderType = 'tabs' | 'navigation' | 'zoom-fade' | 'slide-fade' | 'topics' | 'none'/* | 'counter' */;\n\ntype TransitionSliderOptions = {\n content: HTMLElement,\n type: TransitionSliderType,\n transitionTime: number,\n onTransitionEnd?: (id: number) => void,\n isHeavy?: boolean,\n once?: boolean,\n withAnimationListener?: boolean,\n listenerSetter?: ListenerSetter,\n animateFirst?: boolean\n};\n\ntype TransitionFunction = {\n callback: (tabContent: HTMLElement, prevTabContent: HTMLElement, toRight: boolean) => () => void,\n animateFirst: boolean\n};\n\nconst TransitionSlider = (options: TransitionSliderOptions) => {\n let {\n content,\n type,\n transitionTime,\n onTransitionEnd,\n isHeavy = true,\n once = false,\n withAnimationListener = true,\n listenerSetter,\n animateFirst = false\n } = options;\n\n const {callback: animationFunction, animateFirst: _animateFirst} = transitions[type] || {};\n content.dataset.animation = type;\n\n if(_animateFirst !== undefined) {\n animateFirst = _animateFirst;\n }\n\n const onTransitionEndCallbacks: Map<HTMLElement, Function> = new Map();\n let animationDeferred: CancellablePromise<void>;\n // let animationStarted = 0;\n let from: HTMLElement = null;\n\n if(withAnimationListener) {\n const listenerName = animationFunction ? 'transitionend' : 'animationend';\n\n const onEndEvent = (e: TransitionEvent | AnimationEvent) => {\n cancelEvent(e);\n\n if((e.target as HTMLElement).parentElement !== content) {\n return;\n }\n\n // console.log('Transition: transitionend', /* content, */ e, selectTab.prevId, performance.now() - animationStarted);\n\n const callback = onTransitionEndCallbacks.get(e.target as HTMLElement);\n callback?.();\n\n if(e.target !== from) {\n return;\n }\n\n if(!animationDeferred && isHeavy) return;\n\n if(animationDeferred) {\n animationDeferred.resolve();\n animationDeferred = undefined;\n }\n\n onTransitionEnd?.(selectTab.prevId());\n\n content.classList.remove('animating', 'backwards', 'disable-hover');\n\n if(once) {\n if(listenerSetter) listenerSetter.removeManual(content, listenerName, onEndEvent);\n else content.removeEventListener(listenerName, onEndEvent/* , {capture: false} */);\n from = animationDeferred = undefined;\n onTransitionEndCallbacks.clear();\n }\n };\n\n // TODO: check for transition type (transform, etc) using by animationFunction\n if(listenerSetter) listenerSetter.add(content)(listenerName, onEndEvent);\n else content.addEventListener(listenerName, onEndEvent/* , {passive: true, capture: false} */);\n }\n\n function selectTab(id: number | HTMLElement, animate = true, overrideFrom?: typeof from) {\n if(overrideFrom) {\n from = overrideFrom;\n }\n\n if(id instanceof HTMLElement) {\n id = whichChild(id);\n }\n\n const prevId = selectTab.prevId();\n if(id === prevId) return false;\n\n // console.log('selectTab id:', id);\n\n const to = content.children[id] as HTMLElement;\n\n if(!liteMode.isAvailable('animations') || (prevId === -1 && !animateFirst)) {\n animate = false;\n }\n\n if(!withAnimationListener) {\n const timeout = content.dataset.timeout;\n if(timeout !== undefined) {\n clearTimeout(+timeout);\n }\n\n delete content.dataset.timeout;\n }\n\n if(!animate) {\n if(from) from.classList.remove('active', 'to', 'from');\n else if(to) { // fix instant opening back from closed slider (e.g. instant closening and opening right sidebar)\n const callback = onTransitionEndCallbacks.get(to);\n callback?.();\n }\n\n if(to) {\n to.classList.remove('to', 'from');\n to.classList.add('active');\n }\n\n content.classList.remove('animating', 'backwards', 'disable-hover');\n\n from = to;\n\n onTransitionEnd?.(id);\n return;\n }\n\n if(!withAnimationListener) {\n content.dataset.timeout = '' + window.setTimeout(() => {\n to.classList.remove('to');\n from && from.classList.remove('from');\n content.classList.remove('animating', 'backwards', 'disable-hover');\n delete content.dataset.timeout;\n }, transitionTime);\n }\n\n if(from) {\n from.classList.remove('to');\n from.classList.add('from');\n }\n\n content.classList.add('animating'/* , 'disable-hover' */);\n const toRight = prevId < id;\n content.classList.toggle('backwards', !toRight);\n\n let onTransitionEndCallback: ReturnType<TransitionFunction['callback']>;\n if(!to) {\n // prevTabContent.classList.remove('active');\n } else {\n if(animationFunction) {\n onTransitionEndCallback = animationFunction(to, from, toRight);\n } else {\n to.classList.add('active');\n }\n\n to.classList.remove('from');\n to.classList.add('to');\n }\n\n if(to) {\n const transitionTimeout = to.dataset.transitionTimeout;\n if(transitionTimeout) {\n clearTimeout(+transitionTimeout);\n }\n\n onTransitionEndCallbacks.set(to, () => {\n to.classList.remove('to');\n onTransitionEndCallbacks.delete(to);\n });\n }\n\n if(from/* && false */) {\n let timeout: number;\n const _from = from;\n const callback = () => {\n clearTimeout(timeout);\n _from.classList.remove('active', 'from');\n\n onTransitionEndCallback?.();\n\n onTransitionEndCallbacks.delete(_from);\n };\n\n if(to) {\n timeout = window.setTimeout(callback, transitionTime + 100); // something happened to container\n onTransitionEndCallbacks.set(_from, callback);\n } else {\n timeout = window.setTimeout(callback, transitionTime);\n onTransitionEndCallbacks.set(_from, () => {\n clearTimeout(timeout);\n onTransitionEndCallbacks.delete(_from);\n });\n }\n\n _from.dataset.transitionTimeout = '' + timeout;\n\n if(isHeavy) {\n if(!animationDeferred) {\n animationDeferred = deferredPromise<void>();\n // animationStarted = performance.now();\n }\n\n dispatchHeavyAnimationEvent(animationDeferred, transitionTime * 2);\n }\n }\n\n from = to;\n }\n\n // selectTab.prevId = -1;\n selectTab.prevId = () => from ? whichChild(from) : -1;\n selectTab.getFrom = () => from;\n selectTab.setFrom = (_from: HTMLElement) => from = _from;\n\n return selectTab;\n};\n\nexport default TransitionSlider;\n","export default function isUsernameValid(username: string) {\n return ((username.length >= 3 && username.length <= 32) || !username.length) && /^[a-zA-Z0-9_]*$/.test(username);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport ListenerSetter from '../helpers/listenerSetter';\nimport debounce from '../helpers/schedulers/debounce';\nimport {LangPackKey} from '../lib/langPack';\nimport InputField, {InputFieldOptions, InputState} from './inputField';\nimport isUsernameValid from '../lib/richTextProcessor/isUsernameValid';\nimport {AppManagers} from '../lib/appManagers/managers';\n\nexport class UsernameInputField extends InputField {\n private checkUsernamePromise: Promise<any>;\n private checkUsernameDebounced: (username: string) => void;\n public options: InputFieldOptions & {\n peerId?: PeerId,\n listenerSetter: ListenerSetter,\n onChange?: () => void,\n invalidText: LangPackKey,\n takenText: LangPackKey,\n availableText: LangPackKey,\n head?: string\n };\n public error: ApiError;\n\n constructor(\n options: UsernameInputField['options'],\n private managers: AppManagers\n ) {\n super(options);\n\n this.checkUsernameDebounced = debounce(this.checkUsername.bind(this), 150, false, true);\n\n options.listenerSetter.add(this.input)('input', () => {\n const value = this.getValue();\n\n this.error = undefined;\n if(value === this.originalValue || !value.length) {\n this.setState(InputState.Neutral);\n this.options.onChange?.();\n return;\n } else if(!isUsernameValid(value)) { // does not check the last underscore\n this.setError(this.options.invalidText);\n } else {\n this.setState(InputState.Neutral);\n }\n\n if(this.input.classList.contains('error')) {\n this.options.onChange?.();\n return;\n }\n\n this.checkUsernameDebounced(value);\n });\n }\n\n public getValue() {\n let value = this.value;\n if(this.options.head) {\n value = value.slice(this.options.head.length);\n this.setValueSilently(this.options.head + value);\n }\n\n return value;\n }\n\n private checkUsername(username: string) {\n if(this.checkUsernamePromise) return;\n\n this.error = undefined;\n let checkPromise: Promise<any>\n if(this.options.peerId) {\n checkPromise = this.managers.appChatsManager.checkUsername(this.options.peerId.toChatId(), username);\n } else {\n checkPromise = this.managers.appUsersManager.checkUsername(username);\n }\n\n const promise = this.checkUsernamePromise = checkPromise.then((available) => {\n if(this.getValue() !== username) return;\n\n if(available) {\n this.setState(InputState.Valid, this.options.availableText);\n } else {\n this.setError(this.options.takenText);\n }\n }, (err) => {\n if(this.getValue() !== username) return;\n\n this.error = err;\n switch((err as ApiError).type) {\n case 'USERNAME_PURCHASE_AVAILABLE': {\n this.setError(this.options.takenText);\n break;\n }\n\n case 'USERNAME_INVALID':\n default: {\n this.setError(this.options.invalidText);\n break;\n }\n }\n }).then(() => {\n if(this.checkUsernamePromise === promise) {\n this.checkUsernamePromise = undefined;\n }\n\n this.options.onChange?.();\n\n const value = this.getValue();\n if(value !== username && this.isValidToChange() && isUsernameValid(value)) {\n this.checkUsername(value);\n }\n });\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport findUpAsChild from '../helpers/dom/findUpAsChild';\nimport placeCaretAtEnd from '../helpers/dom/placeCaretAtEnd';\nimport positionElementByIndex from '../helpers/dom/positionElementByIndex';\nimport Sortable from '../helpers/dom/sortable';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport {Middleware} from '../helpers/middleware';\nimport noop from '../helpers/noop';\nimport SortedList, {SortedElementBase} from '../helpers/sortedList';\nimport {Chat, User, Username} from '../layer';\nimport {i18n, LangPackKey} from '../lib/langPack';\nimport rootScope from '../lib/rootScope';\nimport confirmationPopup from './confirmationPopup';\nimport Row from './row';\nimport SettingSection from './settingSection';\nimport {UsernameInputField} from './usernameInputField';\n\nexport default class UsernamesSection extends SettingSection {\n // public section: SettingSection;\n\n constructor(options: {\n peerId: PeerId,\n peer: Chat.channel | User.user,\n listenerSetter: ListenerSetter,\n usernameInputField: UsernameInputField,\n middleware: Middleware\n }) {\n /* const section = this.section = new SettingSection */super({\n name: 'UsernamesProfileHeader',\n caption: !options.peerId.isUser() ? 'UsernamesChannelHelp' : 'UsernamesProfileHelp'\n });\n\n const {peerId, peer, usernameInputField, listenerSetter, middleware} = options;\n const managers = rootScope.managers;\n const channelId = peerId.isUser() ? undefined : peerId.toChatId();\n\n const section = this;\n\n const CLASS_NAME = 'usernames';\n const list = document.createElement('div');\n list.classList.add(CLASS_NAME);\n\n let _usernames: Username[];\n\n interface SortedUsername extends SortedElementBase<string> {\n row: Row\n }\n\n const sortedList = new SortedList<SortedUsername>({\n getIndex: (element) => _usernames.length - _usernames.findIndex((username) => username.username === element.id),\n onDelete: (element) => {\n element.row.container.remove();\n },\n onSort: (element, idx) => {\n positionElementByIndex(element.row.container, list, idx);\n },\n onElementCreate: (base) => {\n const username = _usernames.find((username) => username.username === base.id);\n const row = new Row({\n title: '@' + username.username,\n subtitle: true,\n clickable: true\n });\n\n const editable = !!username.pFlags.editable;\n const active = !!username.pFlags.active;\n\n if(editable) row.container.dataset.editable = '1';\n row.container.dataset.username = username.username;\n row.container.classList.add(CLASS_NAME + '-username');\n row.subtitle.classList.add(CLASS_NAME + '-username-status');\n const media = row.createMedia('medium');\n media.classList.add(CLASS_NAME + '-username-icon', 'tgico');\n\n row.makeSortable();\n\n changeActive(row, active);\n\n (base as SortedUsername).row = row;\n\n return base as SortedUsername;\n }\n });\n\n const changeActive = (row: Row, active: boolean) => {\n row.subtitle.replaceChildren(i18n(row.container.dataset.editable ? 'UsernameLinkEditable' : (active ? 'UsernameLinkActive' : 'UsernameLinkInactive')));\n row.container.classList.toggle('active', active);\n row.toggleSorting(active);\n };\n\n const applyUsernames = (usernames: Username[] = []) => {\n _usernames = usernames;\n\n sortedList.getAll().forEach((element) => {\n if(!usernames.some((username) => username.username === element.id)) {\n sortedList.delete(element.id);\n }\n });\n\n usernames.forEach((username) => {\n if(!sortedList.has(username.username)) {\n sortedList.add(username.username);\n } else {\n const element = sortedList.get(username.username);\n sortedList.update(username.username, element);\n changeActive(element.row, !!username.pFlags.active);\n }\n });\n\n section.container.classList.toggle('hide', !sortedList.getAll().size);\n };\n\n applyUsernames(peer.usernames);\n\n listenerSetter.add(rootScope)('peer_title_edit', async({peerId: _peerId}) => {\n if(_peerId !== peerId) {\n return;\n }\n\n const peer = await managers.appPeersManager.getPeer(peerId);\n applyUsernames((peer as User.user).usernames);\n });\n\n let cancelClick = false;\n attachClickEvent(list, async(e) => {\n if(cancelClick) {\n cancelClick = false;\n return;\n }\n\n const container = findUpAsChild(e.target as HTMLElement, list);\n if(!container) {\n return;\n }\n\n if(container.dataset.editable) {\n placeCaretAtEnd(usernameInputField.input, true, true);\n return;\n }\n\n const username = container.dataset.username;\n\n const active = container.classList.contains('active');\n let titleLangKey: LangPackKey, descriptionLangKey: LangPackKey;\n if(active) {\n titleLangKey = 'UsernameDeactivateLink';\n descriptionLangKey = channelId ? 'UsernameDeactivateLinkChannelMessage' : 'UsernameDeactivateLinkProfileMessage';\n } else {\n titleLangKey = 'UsernameActivateLink';\n descriptionLangKey = channelId ? 'UsernameActivateLinkChannelMessage' : 'UsernameActivateLinkProfileMessage';\n }\n\n try {\n await confirmationPopup({\n titleLangKey,\n descriptionLangKey,\n button: {\n langKey: active ? 'Hide' : 'Show'\n }\n });\n } catch(err) {\n return;\n }\n\n const newActive = !active;\n let promise: Promise<boolean>;\n if(channelId) {\n promise = managers.appChatsManager.toggleUsername(channelId, username, newActive);\n } else {\n promise = managers.appUsersManager.toggleUsername(username, newActive);\n }\n\n promise.catch((err: ApiError) => {\n if(err.type === 'USERNAMES_ACTIVE_TOO_MUCH') {\n confirmationPopup({\n titleLangKey: 'UsernameActivateErrorTitle',\n descriptionLangKey: 'UsernameActivateErrorMessage',\n button: {langKey: 'OK', isCancel: true}\n }).catch(noop);\n } else {\n console.error('turn username error', err);\n }\n });\n });\n\n new Sortable({\n list,\n middleware,\n onSort: (idx, newIdx) => {\n const username = _usernames.splice(idx, 1)[0];\n _usernames.splice(newIdx, 0, username);\n sortedList.updateList();\n // can't just update particular element, have to change indexes\n // sortedList.update(username.username);\n\n const usernames = _usernames.filter((username) => username.pFlags.active).map((username) => username.username);\n if(channelId) {\n managers.appChatsManager.reorderUsernames(channelId, usernames);\n } else {\n managers.appUsersManager.reorderUsernames(usernames);\n }\n }\n });\n\n section.content.append(list);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\ntype TargetType = HTMLElement;\nexport type OnVisibilityChangeItem = {target: TargetType, visible: boolean, entry: IntersectionObserverEntry, index: number};\nexport type OnVisibilityChange = (item: OnVisibilityChangeItem) => void;\n\nexport default class VisibilityIntersector {\n private observer: IntersectionObserver;\n private items: Map<TargetType, boolean> = new Map();\n private locked = false;\n\n constructor(onVisibilityChange: OnVisibilityChange, options?: IntersectionObserverInit) {\n this.observer = new IntersectionObserver((entries) => {\n if(this.locked) {\n return;\n }\n\n const changed: OnVisibilityChangeItem[] = [];\n\n entries.forEach((entry, index) => {\n const target = entry.target as TargetType;\n\n if(this.items.get(target) === entry.isIntersecting) {\n return;\n } else {\n this.items.set(target, entry.isIntersecting);\n }\n\n /* if(entry.isIntersecting) {\n console.log('ooo', entry);\n } */\n\n /* if(this.locked) {\n return;\n } */\n\n const change: typeof changed[0] = {target, visible: entry.isIntersecting, entry, index};\n\n // ! order will be incorrect so can't use it\n // changed[entry.isIntersecting ? 'unshift' : 'push'](change);\n changed.push(change);\n\n // onVisibilityChange(target, entry.isIntersecting);\n });\n\n changed.forEach((item) => {\n onVisibilityChange(item);\n });\n }, options);\n }\n\n public getVisible() {\n const items: TargetType[] = [];\n this.items.forEach((value, key) => {\n if(value) {\n items.push(key);\n }\n });\n\n return items;\n }\n\n public clearVisible() {\n const visible = this.getVisible();\n for(const target of visible) {\n this.items.set(target, false);\n }\n }\n\n public isVisible(target: TargetType) {\n return this.items.get(target);\n }\n\n public disconnect() {\n this.observer.disconnect();\n this.items.clear();\n }\n\n public refresh() {\n this.observer.disconnect();\n\n // window.requestAnimationFrame(() => {\n const targets = [...this.items.keys()];\n for(const target of targets) {\n // this.items.set(target, false);\n this.observer.observe(target);\n }\n // });\n }\n\n public refreshVisible() {\n const visible = this.getVisible();\n for(const target of visible) {\n this.observer.unobserve(target);\n }\n\n for(const target of visible) {\n this.observer.observe(target);\n }\n }\n\n public observe(target: TargetType) {\n this.items.set(target, false);\n this.observer.observe(target);\n }\n\n public unobserve(target: TargetType) {\n this.observer.unobserve(target);\n this.items.delete(target);\n }\n\n public unlock() {\n this.locked = false;\n }\n\n public unlockAndRefresh() {\n this.unlock();\n this.refresh();\n }\n\n public lock() {\n this.locked = true;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport rootScope from '../lib/rootScope';\nimport appMediaPlaybackController from './appMediaPlaybackController';\nimport RangeSelector from './rangeSelector';\n\nexport default class VolumeSelector extends RangeSelector {\n private static ICONS = ['volume_off', 'volume_mute', 'volume_down', 'volume_up'];\n public btn: HTMLElement;\n protected icon: HTMLSpanElement;\n\n constructor(protected listenerSetter: ListenerSetter, protected vertical = false) {\n super({\n step: 0.01,\n min: 0,\n max: 1,\n vertical\n }, 1);\n\n this.setListeners();\n this.setHandlers({\n onScrub: currentTime => {\n const value = Math.max(Math.min(currentTime, 1), 0);\n\n // console.log('volume scrub:', currentTime, value);\n\n appMediaPlaybackController.muted = false;\n appMediaPlaybackController.volume = value;\n }\n\n /* onMouseUp: (e) => {\n cancelEvent(e.event);\n } */\n });\n\n const className = 'player-volume';\n const btn = this.btn = document.createElement('div');\n btn.classList.add('btn-icon', className);\n const icon = this.icon = document.createElement('span');\n icon.classList.add(className + '__icon');\n\n btn.append(icon, this.container);\n\n attachClickEvent(icon, this.onMuteClick, {listenerSetter: this.listenerSetter});\n this.listenerSetter.add(appMediaPlaybackController)('playbackParams', this.setVolume);\n\n this.setVolume();\n }\n\n private onMuteClick = (e?: Event) => {\n e && cancelEvent(e);\n appMediaPlaybackController.muted = !appMediaPlaybackController.muted;\n };\n\n public setVolume = () => {\n // const volume = video.volume;\n const {volume, muted} = appMediaPlaybackController;\n let d: string;\n let iconIndex: number;\n if(!volume || muted) {\n iconIndex = 0;\n } else if(volume > .5) {\n iconIndex = 3;\n } else if(volume > 0 && volume < .25) {\n iconIndex = 1;\n } else {\n iconIndex = 2;\n }\n\n VolumeSelector.ICONS.forEach((icon) => this.icon.classList.remove('tgico-' + icon));\n this.icon.classList.add('tgico-' + VolumeSelector.ICONS[iconIndex]);\n\n if(!this.mousedown) {\n this.setProgress(muted ? 0 : volume);\n }\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MessageEntity} from '../../layer';\nimport wrapRichText from '../../lib/richTextProcessor/wrapRichText';\n\nexport default function wrapCustomEmoji({\n docIds,\n loadPromises,\n middleware,\n lazyLoadQueue,\n customEmojiSize,\n animationGroup\n}: {\n docIds: DocId[],\n loadPromises?: Promise<any>[]\n} & WrapSomethingOptions) {\n const text = ' '.repeat(docIds.length);\n const entities: MessageEntity[] = [];\n docIds.forEach((docId, idx) => {\n entities.push({\n _: 'messageEntityCustomEmoji',\n offset: idx,\n length: 1,\n document_id: docId\n });\n });\n\n const wrapped = wrapRichText(text, {\n entities,\n loadPromises,\n animationGroup,\n customEmojiSize,\n middleware,\n lazyLoadQueue\n });\n\n return wrapped;\n}\n\nexport function wrapCustomEmojiAwaited(options: Parameters<typeof wrapCustomEmoji>[0]) {\n const loadPromises: Promise<any>[] = options.loadPromises ??= [];\n const wrapped = wrapCustomEmoji(options);\n return Promise.all(loadPromises).then(() => wrapped);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport MEDIA_MIME_TYPES_SUPPORTED from '../../environment/mediaMimeTypesSupport';\nimport {CancellablePromise} from '../../helpers/cancellablePromise';\nimport {clearBadCharsAndTrim} from '../../helpers/cleanSearchText';\nimport {formatFullSentTime} from '../../helpers/date';\nimport {simulateClickEvent, attachClickEvent} from '../../helpers/dom/clickEvent';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport formatBytes from '../../helpers/formatBytes';\nimport liteMode from '../../helpers/liteMode';\nimport {MediaSizeType} from '../../helpers/mediaSizes';\nimport noop from '../../helpers/noop';\nimport {Message, MessageMedia, WebPage} from '../../layer';\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport appDownloadManager, {Progress} from '../../lib/appManagers/appDownloadManager';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getDownloadMediaDetails from '../../lib/appManagers/utils/download/getDownloadMediaDetails';\nimport choosePhotoSize from '../../lib/appManagers/utils/photos/choosePhotoSize';\nimport {joinElementsWith} from '../../lib/langPack';\nimport {MAX_FILE_SAVE_SIZE} from '../../lib/mtproto/mtproto_config';\nimport wrapPlainText from '../../lib/richTextProcessor/wrapPlainText';\nimport rootScope from '../../lib/rootScope';\nimport type {ThumbCache} from '../../lib/storages/thumbs';\nimport {MediaSearchContext} from '../appMediaPlaybackController';\nimport AudioElement from '../audio';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport {MiddleEllipsisElement} from '../middleEllipsis';\nimport ProgressivePreloader from '../preloader';\nimport wrapPhoto from './photo';\nimport wrapSenderToPeer from './senderToPeer';\nimport wrapSentTime from './sentTime';\n\nrootScope.addEventListener('document_downloading', (docId) => {\n const elements = Array.from(document.querySelectorAll(`.document[data-doc-id=\"${docId}\"]`)) as HTMLElement[];\n elements.forEach((element) => {\n if(element.querySelector('.preloader-container.manual')) {\n simulateClickEvent(element);\n }\n });\n});\n\nexport default async function wrapDocument({message, withTime, fontWeight, voiceAsMusic, showSender, searchContext, loadPromises, autoDownloadSize, lazyLoadQueue, sizeType, managers = rootScope.managers, cacheContext, fontSize, getSize, canTranscribeVoice}: {\n message: Message.message,\n withTime?: boolean,\n fontWeight?: number,\n voiceAsMusic?: boolean,\n showSender?: boolean,\n searchContext?: MediaSearchContext,\n loadPromises?: Promise<any>[],\n autoDownloadSize?: number,\n lazyLoadQueue?: LazyLoadQueue,\n sizeType?: MediaSizeType,\n managers?: AppManagers,\n cacheContext?: ThumbCache,\n fontSize?: number,\n getSize?: () => number,\n canTranscribeVoice?: boolean\n}): Promise<HTMLElement> {\n fontWeight ??= 500;\n sizeType ??= '' as any;\n fontSize ??= 16;\n const noAutoDownload = autoDownloadSize === 0;\n\n const doc = ((message.media as MessageMedia.messageMediaDocument).document || ((message.media as MessageMedia.messageMediaWebPage).webpage as WebPage.webPage).document) as MyDocument;\n const uploadFileName = message?.uploadingFileName;\n if(doc.type === 'audio' || doc.type === 'voice' || doc.type === 'round') {\n const audioElement = new AudioElement();\n audioElement.withTime = withTime;\n audioElement.message = message;\n audioElement.noAutoDownload = noAutoDownload;\n audioElement.lazyLoadQueue = lazyLoadQueue;\n audioElement.loadPromises = loadPromises;\n if(canTranscribeVoice && doc.type === 'voice') audioElement.transcriptionState = 0;\n (audioElement as any).getSize = getSize;\n\n if(voiceAsMusic) audioElement.voiceAsMusic = voiceAsMusic;\n if(searchContext) audioElement.searchContext = searchContext;\n if(showSender) audioElement.showSender = showSender;\n\n audioElement.dataset.fontWeight = '' + fontWeight;\n audioElement.dataset.fontSize = '' + fontSize;\n audioElement.dataset.sizeType = sizeType;\n await audioElement.render();\n return audioElement;\n }\n\n const extSplitted = doc.file_name ? doc.file_name.split('.') : '';\n let ext = '';\n ext = extSplitted.length > 1 && Array.isArray(extSplitted) ?\n clearBadCharsAndTrim(extSplitted.pop().split(' ', 1)[0].toLowerCase()) :\n 'file';\n\n const docDiv = document.createElement('div');\n docDiv.classList.add('document', `ext-${ext}`);\n docDiv.dataset.docId = '' + doc.id;\n (docDiv as any).doc = doc;\n\n // return docDiv;\n\n const icoDiv = document.createElement('div');\n icoDiv.classList.add('document-ico');\n let icoTextEl: HTMLElement;\n\n const hadContext = !!cacheContext;\n const getCacheContext = () => {\n return hadContext ? cacheContext : managers.thumbsStorage.getCacheContext(doc);\n };\n\n cacheContext = await getCacheContext();\n let hasThumb = false;\n if((doc.thumbs?.length || (message.pFlags.is_outgoing && cacheContext.url && doc.type === 'photo'))/* && doc.mime_type !== 'image/gif' */) {\n docDiv.classList.add('document-with-thumb');\n hasThumb = true;\n\n const imgs: (HTMLImageElement | HTMLCanvasElement | HTMLVideoElement)[] = [];\n // ! WARNING, use thumbs for check when thumb will be generated for media\n if(message.pFlags.is_outgoing && ['photo', 'video'].includes(doc.type) && cacheContext.url) {\n icoDiv.innerHTML = `<img src=\"${cacheContext.url}\">`;\n imgs.push(icoDiv.firstElementChild as HTMLImageElement);\n } else {\n const perf = performance.now();\n const wrapped = await wrapPhoto({\n photo: doc,\n message: null,\n container: icoDiv,\n boxWidth: 54,\n boxHeight: 54,\n loadPromises,\n withoutPreloader: true,\n lazyLoadQueue,\n size: choosePhotoSize(doc, 54, 54, true),\n managers\n });\n // console.log('was wrapping photo', performance.now() - perf);\n icoDiv.style.width = icoDiv.style.height = '';\n if(wrapped.images.thumb) imgs.push(wrapped.images.thumb);\n if(wrapped.images.full) imgs.push(wrapped.images.full);\n }\n\n imgs.forEach((img) => img.classList.add('document-thumb'));\n } else {\n icoTextEl = document.createElement('span');\n icoTextEl.classList.add('document-ico-text');\n icoTextEl.innerText = ext;\n icoDiv.append(icoTextEl);\n }\n\n // let fileName = stringMiddleOverflow(doc.file_name || 'Unknown.file', 26);\n const fileName = doc.file_name ? wrapPlainText(doc.file_name) : 'Unknown.file';\n const descriptionEl = document.createElement('div');\n descriptionEl.classList.add('document-description');\n const bytesContainer = document.createElement('span');\n const bytesEl = formatBytes(doc.size);\n const bytesJoiner = ' / ';\n\n const descriptionParts: (HTMLElement | string | DocumentFragment)[] = [bytesEl];\n\n if(withTime) {\n descriptionParts.push(formatFullSentTime(message.date));\n }\n\n if(showSender) {\n descriptionParts.push(await wrapSenderToPeer(message));\n }\n\n if(!withTime && !showSender) {\n const b = document.createElement('span');\n const bytesMaxEl = formatBytes(doc.size);\n b.append(bytesJoiner, bytesMaxEl);\n b.style.visibility = 'hidden';\n descriptionParts.push(b);\n }\n\n docDiv.innerHTML = `\n ${(cacheContext.downloaded && !uploadFileName) || !message.mid || !hasThumb ? '' : `<div class=\"document-download\"></div>`}\n <div class=\"document-name\"></div>\n <div class=\"document-size\"></div>\n `;\n\n const nameDiv = docDiv.querySelector('.document-name') as HTMLElement;\n const middleEllipsisEl = new MiddleEllipsisElement();\n middleEllipsisEl.dataset.fontWeight = '' + fontWeight;\n middleEllipsisEl.dataset.fontSize = '' + fontSize;\n middleEllipsisEl.dataset.sizeType = sizeType;\n (middleEllipsisEl as any).getSize = getSize;\n middleEllipsisEl.textContent = fileName;\n // setInnerHTML(middleEllipsisEl, fileName);\n\n // * new media popup\n if(!message.mid) {\n docDiv.classList.add('downloaded');\n }\n\n nameDiv.append(middleEllipsisEl);\n\n if(showSender) {\n nameDiv.append(wrapSentTime(message));\n }\n\n const sizeDiv = docDiv.querySelector('.document-size') as HTMLElement;\n bytesContainer.append(...joinElementsWith(descriptionParts, ' · '));\n sizeDiv.append(bytesContainer);\n\n docDiv.prepend(icoDiv);\n\n if(!uploadFileName && message.pFlags.is_outgoing && !message.mid) {\n return docDiv;\n }\n\n let downloadDiv: HTMLElement, preloader: ProgressivePreloader = null;\n const onLoad = () => {\n docDiv.classList.remove('downloading');\n\n if(/* !hasThumb || */(doc.size > MAX_FILE_SAVE_SIZE && !uploadFileName)) {\n preloader.setManual();\n preloader.attach(downloadDiv);\n preloader.preloader.classList.add('manual');\n preloader.setDownloadFunction(load);\n return;\n }\n\n if(doc.size <= MAX_FILE_SAVE_SIZE) {\n docDiv.classList.add('downloaded');\n }\n\n if(downloadDiv) {\n if(downloadDiv !== icoDiv) {\n const _downloadDiv = downloadDiv;\n setTimeout(() => {\n _downloadDiv.remove();\n }, 200);\n }\n\n downloadDiv = null;\n }\n\n if(preloader) {\n preloader = null;\n }\n };\n\n const addByteProgress = (promise: CancellablePromise<any>) => {\n docDiv.classList.add('downloading');\n\n const sizeContainer = document.createElement('span');\n const _bytesContainer = formatBytes(doc.size);\n sizeContainer.style.position = 'absolute';\n sizeContainer.style.left = '0';\n promise.then(onLoad, noop).finally(() => {\n // sizeContainer.replaceWith(bytesContainer);\n bytesContainer.style.visibility = '';\n sizeContainer.remove();\n // b && b.classList.remove('hide');\n });\n\n // b && b.classList.add('hide');\n\n const format = (bytes: number) => formatBytes(bytes);\n let d = format(0);\n bytesContainer.style.visibility = 'hidden';\n // bytesContainer.replaceWith(sizeContainer);\n sizeContainer.append(d, bytesJoiner, _bytesContainer);\n bytesContainer.parentElement.append(sizeContainer);\n promise.addNotifyListener((progress: Progress) => {\n const _d = format(progress.done);\n d.replaceWith(_d);\n d = _d;\n });\n };\n\n // ! DO NOT USE ASYNC/AWAIT HERE ! SAFARI WON'T LET DOWNLOAD THE FILE BECAUSE OF ASYNC\n const load = (e?: Event) => {\n const save = !e || e.isTrusted;\n const doc = (docDiv as any).doc;\n // const doc = await managers.appDocsManager.getDoc(docDiv.dataset.docId);\n let download: CancellablePromise<any>;\n const queueId = appImManager.chat.bubbles ? appImManager.chat.bubbles.lazyLoadQueue.queueId : undefined;\n if(!save) {\n download = appDownloadManager.downloadToDisc({media: doc, queueId}, true);\n } else if(doc.type === 'pdf') {\n const canOpenAfter = /* managers.appDocsManager.downloading.has(doc.id) || */!preloader || preloader.detached;\n download = appDownloadManager.downloadMediaURL({media: doc, queueId});\n if(canOpenAfter) {\n download.then(() => {\n setTimeout(async() => { // wait for preloader animation end\n const url = (await getCacheContext()).url;\n window.open(url);\n }, liteMode.isAvailable('animations') ? 250 : 0);\n });\n }\n } else if(MEDIA_MIME_TYPES_SUPPORTED.has(doc.mime_type) && doc.thumbs?.length) {\n download = appDownloadManager.downloadMediaURL({media: doc, queueId});\n } else {\n download = appDownloadManager.downloadToDisc({media: doc, queueId});\n }\n\n download.catch(() => {\n docDiv.classList.remove('downloading');\n });\n\n if(downloadDiv) {\n preloader.attach(downloadDiv, true, download);\n addByteProgress(download);\n }\n };\n\n const {fileName: downloadFileName} = getDownloadMediaDetails({media: doc, downloadId: '1'});\n if(await managers.apiFileManager.isDownloading(downloadFileName)) {\n downloadDiv = docDiv.querySelector('.document-download') || icoDiv;\n const promise = appDownloadManager.downloadToDisc({media: doc}, true);\n\n preloader = new ProgressivePreloader();\n preloader.attach(downloadDiv, false, promise);\n preloader.setDownloadFunction(load);\n addByteProgress(promise);\n } else if(!cacheContext.downloaded || uploadFileName) {\n downloadDiv = docDiv.querySelector('.document-download') || icoDiv;\n preloader = new ProgressivePreloader({\n isUpload: !!uploadFileName\n });\n\n if(!uploadFileName) {\n preloader.construct();\n preloader.setManual();\n preloader.attach(downloadDiv);\n preloader.setDownloadFunction(load);\n\n if(autoDownloadSize !== undefined && autoDownloadSize >= doc.size) {\n simulateClickEvent(preloader.preloader);\n }\n } else {\n const uploadPromise = appDownloadManager.getUpload(uploadFileName);\n preloader.attachPromise(uploadPromise);\n preloader.attach(downloadDiv);\n addByteProgress(uploadPromise);\n }\n }\n\n attachClickEvent(docDiv, (e) => {\n if(findUpClassName(e.target, 'time')) { // prevent downloading by clicking on time\n return;\n }\n\n if(preloader) {\n preloader.onClick(e);\n } else {\n load(e);\n }\n });\n\n return docDiv;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {formatPhoneNumber} from '../../helpers/formatPhoneNumber';\n\nexport default function formatUserPhone(phone: string) {\n return '+' + formatPhoneNumber(phone).formatted;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport numberThousandSplitter from '../../helpers/number/numberThousandSplitter';\nimport {Chat, ChatParticipants} from '../../layer';\nimport {i18n, LangPackKey} from '../../lib/langPack';\nimport rootScope from '../../lib/rootScope';\n\nexport default async function getChatMembersString(chatId: ChatId, managers = rootScope.managers) {\n const chat: Chat = await managers.appChatsManager.getChat(chatId);\n if(chat._ === 'chatForbidden') {\n return i18n('YouWereKicked');\n }\n\n const chatFull = await managers.appProfileManager.getCachedFullChat(chatId);\n let count: number;\n if(chatFull) {\n if(chatFull._ === 'channelFull') {\n count = chatFull.participants_count;\n } else {\n count = (chatFull.participants as ChatParticipants.chatParticipants).participants?.length;\n }\n } else {\n count = (chat as Chat.chat).participants_count || (chat as any).participants?.participants.length;\n }\n\n const isBroadcast = (chat as Chat.channel).pFlags.broadcast;\n count = count || 1;\n\n const key: LangPackKey = isBroadcast ? 'Peer.Status.Subscribers' : 'Peer.Status.Member';\n return i18n(key, [numberThousandSplitter(count)]);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport _limitSymbols from '../../helpers/string/limitSymbols';\nimport {Chat} from '../../layer';\nimport getPeerActiveUsernames from '../../lib/appManagers/utils/peers/getPeerActiveUsernames';\nimport I18n from '../../lib/langPack';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport rootScope from '../../lib/rootScope';\n\ntype GetPeerTitleOptions = {\n peerId: PeerId,\n plainText?: boolean,\n onlyFirstName?: boolean,\n limitSymbols?: number,\n threadId?: number\n} & Pick<WrapSomethingOptions, 'managers'>;\n\nexport default async function getPeerTitle<T extends GetPeerTitleOptions>(\n options: T\n): Promise<T['plainText'] extends true ? string : DocumentFragment> {\n const {\n peerId = rootScope.myId,\n plainText,\n onlyFirstName,\n limitSymbols,\n managers = rootScope.managers,\n threadId\n } = options;\n\n let title = '';\n if(peerId.isUser()) {\n const user = await managers.appUsersManager.getUser(peerId.toUserId());\n if(user) {\n if(user.first_name) title += user.first_name;\n if(user.last_name && (!onlyFirstName || !title)) title += ' ' + user.last_name;\n }\n\n if(!title) title = !user || user.pFlags.deleted ? I18n.format(onlyFirstName ? 'Deleted' : 'HiddenName', true) : getPeerActiveUsernames(user)[0] || '';\n else title = title.trim();\n } else {\n if(threadId) {\n const topic = await managers.dialogsStorage.getForumTopic(peerId, threadId);\n title = topic?.title || '';\n }\n\n if(!title) {\n const chat = await managers.appChatsManager.getChat(peerId.toChatId()) as Chat.chat;\n title = chat?.title || '';\n }\n\n if(onlyFirstName) {\n title = title.split(' ')[0];\n }\n }\n\n if(limitSymbols !== undefined) {\n title = _limitSymbols(title, limitSymbols, limitSymbols);\n }\n\n return plainText ? title : wrapEmojiText(title) as any;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {formatFullSentTimeRaw} from '../../helpers/date';\nimport {User} from '../../layer';\nimport {LangPackKey, i18n} from '../../lib/langPack';\nimport {REPLIES_PEER_ID, SERVICE_PEER_ID} from '../../lib/mtproto/mtproto_config';\n\nexport default function getUserStatusString(user: User.user): HTMLElement {\n if(!user) {\n return document.createElement('span');\n }\n\n let key: LangPackKey;\n let args: any[];\n\n switch(user.id) {\n case REPLIES_PEER_ID.toUserId():\n key = 'Peer.RepliesNotifications';\n break;\n case SERVICE_PEER_ID.toUserId():\n key = 'Peer.ServiceNotifications';\n break;\n default: {\n if(user.pFlags.bot) {\n key = 'Bot';\n break;\n }\n\n if(user.pFlags.support) {\n key = 'SupportStatus';\n break;\n }\n\n switch(user.status?._) {\n case 'userStatusRecently': {\n key = 'Lately';\n break;\n }\n\n case 'userStatusLastWeek': {\n key = 'WithinAWeek';\n break;\n }\n\n case 'userStatusLastMonth': {\n key = 'WithinAMonth';\n break;\n }\n\n case 'userStatusOffline': {\n const date = user.status.was_online;\n const today = new Date();\n const now = today.getTime() / 1000 | 0;\n\n const diff = now - date;\n if(diff < 60) {\n key = 'Peer.Status.justNow';\n } else if(diff < 3600) {\n key = 'Peer.Status.minAgo';\n const c = diff / 60 | 0;\n args = [c];\n } else if(diff < 86400 && today.getDate() === new Date(date * 1000).getDate()) {\n key = 'LastSeen.HoursAgo';\n const c = diff / 3600 | 0;\n args = [c];\n } else {\n key = 'Peer.Status.LastSeenAt';\n const {dateEl, timeEl} = formatFullSentTimeRaw(date);\n args = [dateEl, timeEl];\n }\n\n break;\n }\n\n case 'userStatusOnline': {\n key = 'Online';\n break;\n }\n\n default: {\n key = 'ALongTimeAgo';\n break;\n }\n }\n\n break;\n }\n }\n\n return i18n(key, args);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport getImageFromStrippedThumb from '../../helpers/getImageFromStrippedThumb';\nimport noop from '../../helpers/noop';\nimport {Document, Photo, PhotoSize} from '../../layer';\nimport DotRenderer from '../dotRenderer';\nimport SetTransition from '../singleTransition';\n\nexport function toggleMediaSpoiler(options: {\n mediaSpoiler: HTMLElement,\n reveal: boolean,\n destroyAfter?: boolean\n}) {\n const {mediaSpoiler, reveal, destroyAfter} = options;\n SetTransition({\n element: mediaSpoiler,\n forwards: reveal,\n className: 'is-revealing',\n duration: 250,\n onTransitionEnd: () => {\n if(reveal && destroyAfter) {\n mediaSpoiler.remove();\n mediaSpoiler.middlewareHelper.destroy();\n }\n }\n });\n}\n\nexport function onMediaSpoilerClick(options: {\n mediaSpoiler: HTMLElement,\n event: Event\n}) {\n const {mediaSpoiler, event} = options;\n cancelEvent(event);\n\n if(mediaSpoiler.classList.contains('is-revealing')) {\n return;\n }\n\n const video = mediaSpoiler.parentElement.querySelector('video');\n if(video && !mediaSpoiler.parentElement.querySelector('.video-play')) {\n video.autoplay = true;\n video.play().catch(noop);\n }\n\n toggleMediaSpoiler({\n mediaSpoiler,\n reveal: true,\n destroyAfter: true\n });\n}\n\nexport function wrapMediaSpoilerWithImage(options: {\n image: Awaited<ReturnType<typeof getImageFromStrippedThumb>>['image']\n} & Parameters<typeof DotRenderer['create']>[0]) {\n const {middleware, image} = options;\n if(!middleware()) {\n return;\n }\n\n image.classList.add('media-spoiler-thumbnail');\n\n const container = document.createElement('div');\n container.classList.add('media-spoiler-container');\n container.middlewareHelper = middleware.create();\n\n const dotRenderer = DotRenderer.create({\n ...options,\n middleware: container.middlewareHelper.get()\n });\n\n container.append(image, dotRenderer.canvas);\n\n return container;\n}\n\nexport default async function wrapMediaSpoiler(\n options: Omit<Parameters<typeof wrapMediaSpoilerWithImage>[0], 'image'> & {\n media: Document.document | Photo.photo\n }\n) {\n const {media} = options;\n const sizes = (media as Photo.photo).sizes || (media as Document.document).thumbs;\n const thumb = sizes.find((size) => size._ === 'photoStrippedSize') as PhotoSize.photoStrippedSize;\n if(!thumb) {\n return;\n }\n\n const {image, loadPromise} = getImageFromStrippedThumb(media, thumb, true);\n await loadPromise;\n\n return wrapMediaSpoilerWithImage({\n ...options,\n image\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyMessage} from '../../lib/appManagers/appMessagesManager';\nimport wrapMessageActionTextNewUnsafe from './messageActionTextNewUnsafe';\n\nexport type WrapMessageActionTextOptions = {\n message: MyMessage,\n plain?: boolean,\n noLinks?: boolean,\n noTextFormat?: boolean\n} & WrapSomethingOptions;\n\nexport default async function wrapMessageActionTextNew<T extends WrapMessageActionTextOptions>(\n options: T\n): Promise<T['plain'] extends true ? string : HTMLElement> {\n try {\n return await wrapMessageActionTextNewUnsafe(options) as any;\n } catch(err) {\n console.error('wrapMessageActionTextNewUnsafe error:', err);\n return options.plain ? '' : document.createElement('span') as any;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {hexaToHsla} from '../helpers/color';\nimport {TOPIC_COLORS} from '../lib/mtproto/mtproto_config';\nimport wrapAbbreviation from '../lib/richTextProcessor/wrapAbbreviation';\n\nlet svg: SVGSVGElement, span: HTMLElement, defs: HTMLElement;\nconst hadColors: Map<number, string> = new Map();\nexport default function topicAvatar(color: number, content: string) {\n if(!svg) {\n defs = document.getElementById('svg-defs') as HTMLElement;\n\n const ns = 'http://www.w3.org/2000/svg';\n\n svg = document.createElementNS(ns, 'svg');\n svg.setAttributeNS(null, 'width', '26');\n svg.setAttributeNS(null, 'height', '26');\n svg.setAttributeNS(null, 'viewBox', '0 0 26 26');\n svg.classList.add('topic-icon-svg');\n\n const use = document.createElementNS(ns, 'use');\n use.setAttributeNS(null, 'href', '#topic-icon');\n svg.append(use);\n\n span = document.createElement('span');\n span.classList.add('topic-icon', 'avatar-like');\n\n const contentSpan = document.createElement('span');\n contentSpan.classList.add('topic-icon-content');\n span.append(svg, contentSpan);\n }\n\n if(!color) {\n console.error('NO TOPIC ICON COLOR!');\n color = TOPIC_COLORS[0];\n }\n\n if(!content) {\n console.error('NO TOPIC NAME!');\n content = '';\n }\n\n const hex = color.toString(16);\n\n const gradientId = `topic-icon-gradient-${color}`;\n let strokeColor = hadColors.get(color);\n if(!strokeColor) {\n const {h, s, l, a} = hexaToHsla('#' + hex);\n defs.insertAdjacentHTML('beforeend', `\n <linearGradient id=\"${gradientId}\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n <stop style=\"stop-color: #${hex};\" offset=\"0%\" />\n <stop style=\"stop-color: hsla(${h}, ${s}%, ${Math.max(0, l - 30)}%, ${a});\" offset=\"100%\" />\n </linearGradient>\n `);\n\n hadColors.set(color, strokeColor = `hsla(${h}, ${s}%, ${Math.max(0, l - 40)}%, ${a})`);\n }\n\n const clone = span.cloneNode(true) as typeof span;\n (clone.firstElementChild as HTMLElement).style.fill = `url(#${gradientId})`;\n // (clone.firstElementChild as HTMLElement).style.stroke = `var(--peer-avatar-${color}-filled)`;\n (clone.firstElementChild as HTMLElement).style.stroke = strokeColor;\n clone.lastElementChild.append(wrapAbbreviation(content, true));\n return clone;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {Message, MessageAction} from '../../layer';\nimport wrapUrl from '../../lib/richTextProcessor/wrapUrl';\n\nexport default function wrapJoinVoiceChatAnchor(message: Message.messageService) {\n const action = message.action as MessageAction.messageActionInviteToGroupCall;\n const {onclick, url} = wrapUrl(`tg://voicechat?chat_id=${message.peerId.toChatId()}&id=${action.call.id}&access_hash=${action.call.access_hash}`);\n if(!onclick) {\n return document.createElement('span');\n }\n\n const a = document.createElement('a');\n a.href = url;\n a.setAttribute('onclick', onclick + '(this)');\n\n return a;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport {formatTime, ONE_DAY} from '../../helpers/date';\nimport htmlToSpan from '../../helpers/dom/htmlToSpan';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport formatCallDuration from '../../helpers/formatCallDuration';\nimport paymentsWrapCurrencyAmount from '../../helpers/paymentsWrapCurrencyAmount';\nimport {ForumTopic, Message, MessageAction} from '../../layer';\nimport getPeerId from '../../lib/appManagers/utils/peers/getPeerId';\nimport I18n, {FormatterArgument, FormatterArguments, i18n, join, langPack, LangPackKey, _i18n} from '../../lib/langPack';\nimport {GENERAL_TOPIC_ID} from '../../lib/mtproto/mtproto_config';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport wrapPlainText from '../../lib/richTextProcessor/wrapPlainText';\nimport wrapRichText from '../../lib/richTextProcessor/wrapRichText';\nimport rootScope from '../../lib/rootScope';\nimport topicAvatar from '../topicAvatar';\nimport {wrapCustomEmojiAwaited} from './customEmoji';\nimport getPeerTitle from './getPeerTitle';\nimport wrapJoinVoiceChatAnchor from './joinVoiceChatAnchor';\nimport {WrapMessageActionTextOptions} from './messageActionTextNew';\nimport wrapMessageForReply, {WrapMessageForReplyOptions} from './messageForReply';\nimport wrapPeerTitle from './peerTitle';\n\nasync function wrapLinkToMessage(options: WrapMessageForReplyOptions) {\n const wrapped = await wrapMessageForReply(options);\n\n if(options.plain) {\n return wrapped;\n }\n\n const a = document.createElement('i');\n a.dataset.savedFrom = (options.message as Message.message).peerId + '_' + (options.message as Message.message).mid;\n a.dir = 'auto';\n a.append(wrapped);\n return a;\n}\n\nfunction wrapSomeText(text: string, plain?: boolean) {\n return plain ? text : htmlToSpan(wrapEmojiText(text));\n}\n\ntype WrapTopicIconOptions = {\n topic: Pick<ForumTopic.forumTopic, 'icon_color' | 'icon_emoji_id' | 'title' | 'id'>,\n plain?: boolean\n} & WrapSomethingOptions;\nexport async function wrapTopicIcon<T extends WrapTopicIconOptions>(options: T): Promise<T['plain'] extends true ? string : HTMLElement | DocumentFragment> {\n const topic = options.topic;\n\n let iconEmojiId = topic?.icon_emoji_id;\n if(topic?.id === GENERAL_TOPIC_ID) {\n iconEmojiId = '5390854796011906616';\n }\n\n if(!iconEmojiId) {\n if(options.plain) return '' as any;\n\n // if(topic?.id === GENERAL_TOPIC_ID) {\n // const span = document.createElement('span');\n // span.innerHTML = `\n // <svg class=\"topic-icon-general\" width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" xmlns=\"http://www.w3.org/2000/svg\">\n // <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M11.2788 4.3654C11.4806 3.65912 11.0717 2.92299 10.3654 2.72119C9.65911 2.5194 8.92297 2.92836 8.72118 3.63464L7.85393 6.67H6C5.26546 6.67 4.67 7.26546 4.67 8C4.67 8.73454 5.26546 9.33 6 9.33H7.09393L6.13965 12.67H4C3.26546 12.67 2.67 13.2655 2.67 14C2.67 14.7345 3.26546 15.33 4 15.33H5.37965L4.72118 17.6346C4.51938 18.3409 4.92835 19.0771 5.63463 19.2788C6.3409 19.4806 7.07704 19.0717 7.27883 18.3654L8.14609 15.33H11.3796L10.7212 17.6346C10.5194 18.3409 10.9283 19.0771 11.6346 19.2788C12.3409 19.4806 13.077 19.0717 13.2788 18.3654L14.1461 15.33H16C16.7345 15.33 17.33 14.7345 17.33 14C17.33 13.2655 16.7345 12.67 16 12.67H14.9061L15.8604 9.33H18C18.7345 9.33 19.33 8.73454 19.33 8C19.33 7.26546 18.7345 6.67 18 6.67H16.6204L17.2788 4.3654C17.4806 3.65912 17.0717 2.92299 16.3654 2.72119C15.6591 2.5194 14.923 2.92836 14.7212 3.63464L13.8539 6.67H10.6204L11.2788 4.3654ZM9.86037 9.33L8.90609 12.67H12.1396L13.0939 9.33H9.86037Z\"/>\n // </svg>\n // `;\n\n // span.classList.add('topic-icon');\n\n // return span as any;\n // }\n\n return topicAvatar(topic?.icon_color, topic?.title) as any;\n }\n\n return options.plain ?\n rootScope.managers.appEmojiManager.getCustomEmojiDocument(iconEmojiId).then((doc) => doc.stickerEmojiRaw) :\n wrapCustomEmojiAwaited({\n ...options,\n docIds: [iconEmojiId]\n }).then((fragment) => {\n fragment.lastElementChild.classList.add('topic-icon');\n return fragment;\n }) as any;\n}\n\nfunction wrapMessageActionTopicIcon(options: WrapMessageActionTextOptions) {\n const action = ((options.message as Message.messageService).action as MessageAction.messageActionTopicCreate);\n return wrapTopicIcon({\n ...options,\n topic: action as any as ForumTopic.forumTopic\n });\n}\n\nasync function wrapMessageActionTopicIconAndName(options: WrapMessageActionTextOptions) {\n const action = ((options.message as Message.messageService).action as MessageAction.messageActionTopicCreate);\n const span = document.createElement('span');\n span.classList.add('topic-name');\n span.append(await wrapMessageActionTopicIcon(options), wrapSomeText(action.title, options.plain));\n return span;\n}\n\nexport default async function wrapMessageActionTextNewUnsafe(options: WrapMessageActionTextOptions) {\n const {plain, message, noLinks} = options;\n const element: HTMLElement = plain ? undefined : document.createElement('span');\n const action = 'action' in message && message.action;\n\n // this.log('message action:', action);\n\n if((action as MessageAction.messageActionCustomAction).message) {\n const unsafeMessage = (action as MessageAction.messageActionCustomAction).message;\n if(plain) {\n return wrapPlainText(unsafeMessage);\n } else {\n setInnerHTML(element, wrapRichText(unsafeMessage, {noLinebreaks: true}));\n return element;\n }\n } else {\n let _ = action._;\n // let suffix = '';\n let langPackKey: LangPackKey;\n let args: Array<FormatterArgument | Promise<FormatterArgument>>;\n\n const managers = rootScope.managers;\n\n const getNameDivHTML = (peerId: PeerId, plain: boolean) => {\n return plain ? getPeerTitle({peerId, plainText: plain}) : wrapPeerTitle({peerId});\n };\n\n switch(action._) {\n case 'messageActionPhoneCall': {\n _ += '.' + (action as any).type;\n\n args = [formatCallDuration(action.duration, plain)];\n break;\n }\n\n case 'messageActionGroupCall': {\n _ += '.' + (action as any).type;\n\n args = [];\n if(!_.endsWith('You') && !message.pFlags.post) {\n args.push(getNameDivHTML(message.fromId, plain));\n }\n\n if(action.duration !== undefined) {\n args.push(formatCallDuration(action.duration, plain));\n } else if(noLinks) {\n args.push('');\n } else {\n args.push(wrapJoinVoiceChatAnchor(message as any));\n }\n\n break;\n }\n\n case 'messageActionInviteToGroupCall': {\n const peerIds = [message.fromId, action.users[0].toPeerId()];\n let a = 'Chat.Service.VoiceChatInvitation';\n const myId = rootScope.myId;\n if(peerIds[0] === myId) a += 'ByYou';\n else if(peerIds[1] === myId) a += 'ForYou';\n indexOfAndSplice(peerIds, myId);\n\n langPackKey = a as LangPackKey;\n args = peerIds.map((peerId) => getNameDivHTML(peerId, plain));\n args.push(noLinks ? '' : wrapJoinVoiceChatAnchor(message as any));\n break;\n }\n\n case 'messageActionGroupCallScheduled': {\n const today = new Date();\n const date = new Date(action.schedule_date * 1000);\n const daysToStart = (date.getTime() - today.getTime()) / 86400e3;\n const tomorrowDate = new Date(today);\n tomorrowDate.setDate(tomorrowDate.getDate() + 1);\n\n const isBroadcast = await managers.appPeersManager.isBroadcast(message.peerId);\n langPackKey = isBroadcast ? 'ChatList.Service.VoiceChatScheduled.Channel' : 'ChatList.Service.VoiceChatScheduled';\n args = [];\n const myId = rootScope.myId;\n if(message.fromId === myId) {\n langPackKey += 'You';\n } else if(!isBroadcast) {\n args.push(getNameDivHTML(message.fromId, plain));\n }\n\n let k: LangPackKey;\n const _args: FormatterArguments = [];\n if(daysToStart < 1 && date.getDate() === today.getDate()) {\n k = 'TodayAtFormattedWithToday';\n } else if(daysToStart < 2 && date.getDate() === tomorrowDate.getDate()) {\n k = 'Time.TomorrowAt';\n } else {\n k = 'formatDateAtTime';\n _args.push(new I18n.IntlDateElement({\n date,\n options: {\n day: '2-digit',\n month: '2-digit',\n year: '2-digit'\n }\n }).element);\n }\n\n _args.push(formatTime(date));\n const t = i18n(k, _args);\n args.push(t);\n\n break;\n }\n\n case 'messageActionChatCreate': {\n const myId = rootScope.myId;\n if(message.fromId === myId) {\n _ += 'You';\n } else {\n args = [getNameDivHTML(message.fromId, plain)];\n }\n\n break;\n }\n\n case 'messageActionPinMessage': {\n const peerId = message.peerId;\n const pinnedMessage = await managers.appMessagesManager.getMessageByPeer(peerId, message.reply_to_mid);\n\n args = [\n getNameDivHTML(message.fromId, plain)\n ];\n\n if(!pinnedMessage/* || true */) {\n langPackKey = 'ActionPinnedNoText';\n\n if(message.reply_to_mid) { // refresh original message\n managers.appMessagesManager.fetchMessageReplyTo(message);\n }\n } else {\n args.push(wrapLinkToMessage({\n ...options,\n message: pinnedMessage\n }));\n }\n\n break;\n }\n\n case 'messageActionChatJoinedByRequest': {\n const isBroadcast = await managers.appPeersManager.isBroadcast(message.peerId);\n if(message.pFlags.out) {\n langPackKey = isBroadcast ? 'RequestToJoinChannelApproved' : 'RequestToJoinGroupApproved';\n } else {\n langPackKey = isBroadcast ? 'ChatService.UserJoinedChannelByRequest' : 'ChatService.UserJoinedGroupByRequest';\n args = [getNameDivHTML(message.fromId, plain)];\n }\n break;\n }\n\n case 'messageActionContactSignUp':\n case 'messageActionChatReturn':\n case 'messageActionChatLeave':\n case 'messageActionChatJoined':\n case 'messageActionChatEditPhoto':\n case 'messageActionChatDeletePhoto':\n case 'messageActionChatEditVideo':\n case 'messageActionChatJoinedByLink':\n case 'messageActionChannelEditVideo':\n case 'messageActionChannelDeletePhoto': {\n args = [getNameDivHTML(message.fromId, plain)];\n break;\n }\n\n case 'messageActionChannelEditTitle':\n case 'messageActionChatEditTitle': {\n args = [];\n if(action._ === 'messageActionChatEditTitle') {\n args.push(getNameDivHTML(message.fromId, plain));\n }\n\n args.push(wrapSomeText(action.title));\n break;\n }\n\n case 'messageActionChatDeleteUser':\n case 'messageActionChatAddUsers':\n case 'messageActionChatAddUser': {\n const users = (action as MessageAction.messageActionChatAddUser).users ||\n [(action as MessageAction.messageActionChatDeleteUser).user_id];\n\n args = [getNameDivHTML(message.fromId, plain)];\n\n if(users.length > 1) {\n const joined = join(\n await Promise.all(users.map((userId: UserId) => getNameDivHTML(userId.toPeerId(), plain))),\n false,\n plain\n );\n\n if(plain) {\n args.push(...joined);\n } else {\n const fragment = document.createElement('span');\n fragment.append(...joined);\n args.push(fragment);\n }\n } else {\n args.push(getNameDivHTML(users[0].toPeerId(), plain));\n }\n\n break;\n }\n\n case 'messageActionBotAllowed': {\n if(action.pFlags?.attach_menu) {\n langPackKey = 'ActionAttachMenuBotAllowed';\n break;\n } else if(!action.domain) {\n break;\n }\n\n const anchorHTML = wrapRichText(action.domain, {\n entities: [{\n _: 'messageEntityUrl',\n length: action.domain.length,\n offset: 0\n }],\n noLinks\n });\n\n const node = htmlToSpan(anchorHTML);\n\n args = [node];\n break;\n }\n\n case 'messageActionPaymentSent': {\n const isRecurringInit = action.pFlags.recurring_init;\n const isRecurringUsed = action.pFlags.recurring_used;\n langPackKey = isRecurringUsed ? 'Chat.Service.PaymentSentRecurringUsedNoTitle' : (isRecurringInit ? 'Chat.Service.PaymentSentRecurringInitNoTitle' : 'Chat.Service.PaymentSent1NoTitle');\n const price = paymentsWrapCurrencyAmount(action.total_amount, action.currency);\n args = [price, getNameDivHTML(message.peerId, plain)];\n\n if(message.reply_to_mid) {\n const invoiceMessage = await managers.appMessagesManager.getMessageByPeer(\n message.reply_to?.reply_to_peer_id ? getPeerId(message.reply_to.reply_to_peer_id) : message.peerId,\n message.reply_to_mid\n );\n\n if(!invoiceMessage) {\n managers.appMessagesManager.fetchMessageReplyTo(message);\n } else {\n langPackKey = isRecurringUsed ? 'Chat.Service.PaymentSentRecurringUsed' : (isRecurringInit ? 'Chat.Service.PaymentSentRecurringInit' : 'Chat.Service.PaymentSent1');\n args.push(wrapLinkToMessage({\n ...options,\n message: invoiceMessage\n }).then((el) => {\n if(el instanceof HTMLElement) {\n el.classList.add('is-receipt-link');\n }\n\n return el;\n }));\n }\n }\n\n break;\n }\n\n case 'messageActionSetMessagesTTL': {\n args = [];\n\n const isBroadcast = await managers.appPeersManager.isBroadcast(message.peerId);\n if(action.period) {\n if(isBroadcast) {\n langPackKey = 'ActionTTLChannelChanged';\n } else if(message.fromId === rootScope.myId) {\n langPackKey = 'ActionTTLYouChanged';\n } else {\n langPackKey = 'ActionTTLChanged';\n args.push(getNameDivHTML(message.fromId, plain));\n }\n\n let duration: ReturnType<typeof formatCallDuration>;\n if(action.period > 1814400) {\n let key: LangPackKey;\n const args: FormatterArguments = [];\n const year = 31536000;\n if(action.period >= year) {\n key = 'Years';\n args.push(action.period / year | 0);\n } else {\n key = 'Months';\n args.push(action.period / (ONE_DAY * 30) | 0);\n }\n\n duration = plain ? I18n.format(key, true, args) : i18n(key, args);\n } else {\n duration = formatCallDuration(action.period, plain);\n }\n\n args.push(duration);\n } else {\n if(isBroadcast) {\n langPackKey = 'ActionTTLChannelDisabled';\n } else if(message.fromId === rootScope.myId) {\n langPackKey = 'ActionTTLYouDisabled';\n } else {\n langPackKey = 'ActionTTLDisabled';\n args.push(getNameDivHTML(message.fromId, plain));\n }\n }\n break;\n }\n\n case 'messageActionTopicEdit': {\n let iconElement: (typeof args)[0];\n let titleElement: typeof iconElement;\n let authorElement: ReturnType<typeof getNameDivHTML>;\n const isMe = !!message.pFlags.out;\n const isIconChanged = action.icon_emoji_id !== undefined;\n const isIconRemoved = isIconChanged && !+action.icon_emoji_id;\n const isTitleChanged = action.title !== undefined;\n const isHiddenChanged = action.hidden !== undefined;\n\n if(!isMe) {\n authorElement = getNameDivHTML(message.fromId, plain);\n }\n\n if(isTitleChanged) {\n titleElement = wrapSomeText(action.title);\n }\n\n if(isIconChanged && !isIconRemoved) {\n iconElement = wrapMessageActionTopicIcon(options);\n }\n\n args = authorElement ? [authorElement] : [];\n\n if(action.closed) {\n langPackKey = isMe ? 'Chat.Service.Group.TopicEdited.You.Paused' : 'Chat.Service.Group.TopicEdited.Paused';\n } else if(action.closed === false) {\n langPackKey = isMe ? 'Chat.Service.Group.TopicEdited.You.Resumed' : 'Chat.Service.Group.TopicEdited.Resumed';\n } else if(isIconRemoved && isTitleChanged) {\n langPackKey = isMe ? 'Chat.Service.TopicEdited.You.Mixed.IconRemoved' : 'Chat.Service.TopicEdited.Mixed.IconRemoved';\n args.push(titleElement);\n } else if(isIconChanged && isTitleChanged) {\n langPackKey = isMe ? 'Chat.Service.TopicEdited.You.Mixed' : 'Chat.Service.TopicEdited.Mixed';\n args.push(wrapMessageActionTopicIconAndName(options));\n } else if(isIconRemoved) {\n langPackKey = isMe ? 'Chat.Service.Group.TopicEdited.You.Icon.Removed' : 'Chat.Service.Group.TopicEdited.Icon.Removed';\n } else if(isTitleChanged) {\n langPackKey = isMe ? 'Chat.Service.Group.TopicEdited.You.Title' : 'Chat.Service.Group.TopicEdited.Title';\n args.push(titleElement);\n } else if(isIconChanged) {\n langPackKey = isMe ? 'Chat.Service.Group.TopicEdited.You.Icon' : 'Chat.Service.Group.TopicEdited.Icon';\n args.push(iconElement);\n } else if(isHiddenChanged) {\n langPackKey = isMe ?\n (action.hidden ? 'Chat.Service.Group.TopicEdited.You.Hided' : 'Chat.Service.Group.TopicEdited.You.Unhided') :\n (action.hidden ? 'Chat.Service.Group.TopicEdited.Hided' : 'Chat.Service.Group.TopicEdited.Unhided');\n }\n\n break;\n }\n\n case 'messageActionTopicCreate': {\n args = [wrapMessageActionTopicIconAndName(options)];\n langPackKey = 'TopicWasCreatedAction';\n break;\n }\n\n case 'messageActionSetChatTheme': {\n const isMe = !!message.pFlags.out;\n let authorElement: ReturnType<typeof getNameDivHTML>;\n if(!isMe) {\n authorElement = getNameDivHTML(message.fromId, plain);\n }\n\n args = authorElement ? [authorElement] : [];\n\n if(action.emoticon) {\n args.push(wrapEmojiText(action.emoticon));\n langPackKey = isMe ? 'ChatThemeChangedYou' : 'ChatThemeChangedTo';\n } else {\n langPackKey = isMe ? 'ChatThemeDisabledYou' : 'ChatThemeDisabled';\n }\n break;\n }\n\n case 'messageActionGiftPremium': {\n const isMe = !!message.pFlags.out;\n let authorElement: ReturnType<typeof getNameDivHTML>;\n if(!isMe) {\n authorElement = getNameDivHTML(message.fromId, plain);\n }\n\n args = authorElement ? [authorElement] : [];\n\n args.push(paymentsWrapCurrencyAmount(action.amount, action.currency, false, true));\n\n langPackKey = isMe ? 'ActionGiftOutbound' : 'ActionGiftInbound';\n\n break;\n }\n\n default:\n langPackKey = (langPack[_] || `[${action._}]`) as any;\n break;\n }\n\n if(!langPackKey) {\n langPackKey = langPack[_];\n if(langPackKey === undefined) {\n langPackKey = '[' + _ + ']' as any;\n }\n }\n\n const waited = args && await Promise.all(args);\n\n if(plain) {\n return I18n.format(langPackKey, true, waited);\n } else {\n // if(waited && noLinks) {\n // waited = waited.map((arg) => arg instanceof HTMLAnchorElement ? arg.textContent : arg);\n // }\n\n return _i18n(element, langPackKey, waited);\n }\n\n // str = !langPackKey || langPackKey[0].toUpperCase() === langPackKey[0] ? langPackKey : getNameDivHTML(message.fromId) + langPackKey + (suffix ? ' ' : '');\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport assumeType from '../../helpers/assumeType';\nimport htmlToDocumentFragment from '../../helpers/dom/htmlToDocumentFragment';\nimport {getRestrictionReason} from '../../helpers/restrictions';\nimport escapeRegExp from '../../helpers/string/escapeRegExp';\nimport limitSymbols from '../../helpers/string/limitSymbols';\nimport {Message, DocumentAttribute, DraftMessage} from '../../layer';\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport {MyDraftMessage} from '../../lib/appManagers/appDraftsManager';\nimport {MyMessage} from '../../lib/appManagers/appMessagesManager';\nimport isMessageRestricted from '../../lib/appManagers/utils/messages/isMessageRestricted';\nimport I18n, {LangPackKey, i18n, UNSUPPORTED_LANG_PACK_KEY} from '../../lib/langPack';\nimport parseEntities from '../../lib/richTextProcessor/parseEntities';\nimport sortEntities from '../../lib/richTextProcessor/sortEntities';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport wrapPlainText from '../../lib/richTextProcessor/wrapPlainText';\nimport wrapRichText from '../../lib/richTextProcessor/wrapRichText';\nimport rootScope from '../../lib/rootScope';\nimport {Modify} from '../../types';\nimport wrapMessageActionTextNew, {WrapMessageActionTextOptions} from './messageActionTextNew';\n\nexport type WrapMessageForReplyOptions = Modify<WrapMessageActionTextOptions, {\n message: MyMessage | MyDraftMessage\n}> & {\n text?: string,\n usingMids?: number[],\n highlightWord?: string,\n withoutMediaType?: boolean\n};\n\n// export default async function wrapMessageForReply(message: MyMessage | MyDraftMessage, text: string, usingMids: number[], plain: true, highlightWord?: string, withoutMediaType?: boolean): Promise<string>;\n// export default async function wrapMessageForReply(message: MyMessage | MyDraftMessage, text?: string, usingMids?: number[], plain?: false, highlightWord?: string, withoutMediaType?: boolean): Promise<DocumentFragment>;\n// export default async function wrapMessageForReply(message: MyMessage | MyDraftMessage, text: string = (message as Message.message).message, usingMids?: number[], plain?: boolean, highlightWord?: string, withoutMediaType?: boolean): Promise<DocumentFragment | string> {\nexport default async function wrapMessageForReply<T extends WrapMessageForReplyOptions>(\n options: T\n): Promise<T['plain'] extends true ? string : DocumentFragment> {\n let {message, text, usingMids, plain, highlightWord, withoutMediaType} = options;\n text ??= (message as Message.message).message;\n\n const parts: (Node | string)[] = [];\n\n let hasAlbumKey = false;\n const addPart = (langKey: LangPackKey, part?: string | HTMLElement | DocumentFragment) => {\n if(langKey) {\n if(part === undefined && hasAlbumKey) {\n return;\n }\n\n part = plain ? I18n.format(langKey, true) : i18n(langKey);\n }\n\n if(plain) {\n parts.push(part);\n } else {\n const el = document.createElement('span');\n if(typeof(part) === 'string') el.innerHTML = part;\n else el.append(part);\n parts.push(el);\n }\n };\n\n const managers = rootScope.managers;\n const appMessagesManager = managers.appMessagesManager;\n\n const isRestricted = isMessageRestricted(message as any);\n\n let entities = (message as Message.message).totalEntities ?? (message as DraftMessage.draftMessage).entities;\n if((message as Message.message).media && !isRestricted) {\n assumeType<Message.message>(message);\n let usingFullAlbum = true;\n if(message.grouped_id) {\n if(usingMids) {\n const mids = await appMessagesManager.getMidsByMessage(message);\n if(usingMids.length === mids.length) {\n for(const mid of mids) {\n if(!usingMids.includes(mid)) {\n usingFullAlbum = false;\n break;\n }\n }\n } else {\n usingFullAlbum = false;\n }\n }\n\n if(usingFullAlbum) {\n const albumText = await appMessagesManager.getAlbumText(message.grouped_id);\n text = albumText?.message || '';\n entities = albumText?.totalEntities || [];\n\n if(!withoutMediaType) {\n addPart('AttachAlbum');\n hasAlbumKey = true;\n }\n }\n } else {\n usingFullAlbum = false;\n }\n\n if((!usingFullAlbum && !withoutMediaType) || !text) {\n const media = message.media;\n switch(media._) {\n case 'messageMediaPhoto':\n addPart('AttachPhoto');\n break;\n case 'messageMediaDice':\n addPart(undefined, plain ? media.emoticon : wrapEmojiText(media.emoticon));\n break;\n case 'messageMediaVenue': {\n text = media.title;\n addPart('AttachLocation');\n break;\n }\n case 'messageMediaGeo':\n addPart('AttachLocation');\n break;\n case 'messageMediaGeoLive':\n addPart('AttachLiveLocation');\n break;\n case 'messageMediaPoll':\n const f = '📊' + ' ' + (media.poll.question || 'poll');\n addPart(undefined, plain ? f : wrapEmojiText(f));\n break;\n case 'messageMediaContact':\n addPart('AttachContact');\n break;\n case 'messageMediaGame': {\n const f = '🎮' + ' ' + media.game.title;\n addPart(undefined, plain ? f : wrapEmojiText(f));\n break;\n }\n case 'messageMediaDocument': {\n const document = media.document as MyDocument;\n\n if(document.type === 'video') {\n addPart('AttachVideo');\n } else if(document.type === 'voice') {\n addPart('AttachAudio');\n } else if(document.type === 'gif') {\n addPart('AttachGif');\n } else if(document.type === 'round') {\n addPart('AttachRound');\n } else if(document.type === 'sticker') {\n const i = parts.length;\n if(document.stickerEmojiRaw) {\n const f = document.stickerEmojiRaw + ' ';\n addPart(undefined, plain ? f : wrapEmojiText(f));\n }\n\n addPart('AttachSticker');\n\n // will combine two parts into one\n const p = parts.splice(i, 2);\n if(plain) parts.push((p[0] as string) + (p[1] ? p[1] as string : ''));\n else {\n const span = window.document.createElement('span');\n span.append(...p);\n parts.push(span);\n }\n\n text = '';\n } else if(document.type === 'audio') {\n const attribute = document.attributes.find((attribute) => attribute._ === 'documentAttributeAudio' && (attribute.title || attribute.performer)) as DocumentAttribute.documentAttributeAudio;\n const f = '🎵' + ' ' + (attribute ? [attribute.title, attribute.performer].filter(Boolean).join(' - ') : document.file_name);\n addPart(undefined, plain ? f : wrapEmojiText(f));\n } else {\n addPart(undefined, plain ? document.file_name : wrapEmojiText(document.file_name));\n }\n\n break;\n }\n\n case 'messageMediaInvoice': {\n if(media.extended_media?._ === 'messageExtendedMediaPreview') {\n addPart(undefined, plain ? media.description : wrapEmojiText(media.description));\n } else {\n addPart(undefined, plain ? media.title : wrapEmojiText(media.title));\n }\n\n break;\n }\n\n case 'messageMediaUnsupported': {\n addPart(UNSUPPORTED_LANG_PACK_KEY);\n break;\n }\n\n default:\n // messageText += media._;\n // /////appMessagesManager.log.warn('Got unknown media type!', message);\n break;\n }\n }\n\n const length = parts.length;\n for(let i = 1; i < length; i += 2) {\n parts.splice(i, 0, ', ');\n }\n\n if(text && length) {\n parts.push(', ');\n }\n }\n\n if((message as Message.messageService).action) {\n const actionWrapped = await wrapMessageActionTextNew({\n message: (message as Message.messageService),\n plain,\n noLinks: true,\n noTextFormat: true\n });\n\n if(actionWrapped) {\n addPart(undefined, actionWrapped);\n }\n }\n\n if(isRestricted) {\n text = getRestrictionReason((message as Message.message).restriction_reason).text;\n entities = [];\n }\n\n if(text) {\n text = limitSymbols(text, 100);\n\n entities ??= parseEntities(text);\n\n if(plain) {\n parts.push(wrapPlainText(text, entities));\n } else {\n // let entities = parseEntities(text.replace(/\\n/g, ' '));\n\n if(highlightWord) {\n highlightWord = highlightWord.trim();\n let found = false;\n let match: any;\n const regExp = new RegExp(escapeRegExp(highlightWord), 'gi');\n entities = entities.slice(); // fix leaving highlight entity\n while((match = regExp.exec(text)) !== null) {\n entities.push({_: 'messageEntityHighlight', length: highlightWord.length, offset: match.index});\n found = true;\n }\n\n if(found) {\n sortEntities(entities);\n }\n }\n\n const messageWrapped = wrapRichText(text, {\n noLinebreaks: true,\n entities,\n noLinks: true,\n noTextFormat: true\n });\n\n parts.push(htmlToDocumentFragment(messageWrapped));\n }\n }\n\n if(plain) {\n return parts.join('') as any;\n } else {\n const fragment = document.createDocumentFragment();\n fragment.append(...parts);\n return fragment as any;\n }\n}\n","import getParticipantRank from '../../lib/appManagers/utils/chats/getParticipantRank';\nimport {i18n} from '../../lib/langPack';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\n\nexport default function wrapParticipantRank(rank: ReturnType<typeof getParticipantRank> | 0) {\n return typeof(rank) === 'number' ?\n i18n(!rank ? 'Chat.ChannelBadge' : (rank === 1 ? 'Chat.OwnerBadge' : 'ChatAdmin')) :\n wrapEmojiText(rank);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PeerTitle, {PeerTitleOptions} from '../peerTitle';\n\nexport default async function wrapPeerTitle(options: PeerTitleOptions) {\n const peerTitle = new PeerTitle();\n await peerTitle.update(options);\n return peerTitle.element;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport renderMediaWithFadeIn from '../../helpers/dom/renderMediaWithFadeIn';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport {Message, PhotoSize, VideoSize, WebDocument} from '../../layer';\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport {MyPhoto} from '../../lib/appManagers/appPhotosManager';\nimport rootScope from '../../lib/rootScope';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport ProgressivePreloader from '../preloader';\nimport blur from '../../helpers/blur';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getStrippedThumbIfNeeded from '../../helpers/getStrippedThumbIfNeeded';\nimport setAttachmentSize from '../../helpers/setAttachmentSize';\nimport choosePhotoSize from '../../lib/appManagers/utils/photos/choosePhotoSize';\nimport type {ThumbCache} from '../../lib/storages/thumbs';\nimport appDownloadManager from '../../lib/appManagers/appDownloadManager';\nimport isWebDocument from '../../lib/appManagers/utils/webDocs/isWebDocument';\nimport createVideo from '../../helpers/dom/createVideo';\nimport noop from '../../helpers/noop';\nimport {THUMB_TYPE_FULL} from '../../lib/mtproto/mtproto_config';\nimport {Middleware} from '../../helpers/middleware';\nimport liteMode from '../../helpers/liteMode';\n\nexport default async function wrapPhoto({photo, message, container, boxWidth, boxHeight, withTail, isOut, lazyLoadQueue, middleware, size, withoutPreloader, loadPromises, autoDownloadSize, noBlur, noThumb, noFadeIn, blurAfter, managers = rootScope.managers, processUrl}: {\n photo: MyPhoto | MyDocument | WebDocument,\n message?: Message.message | Message.messageService,\n container: HTMLElement,\n boxWidth?: number,\n boxHeight?: number,\n withTail?: boolean,\n isOut?: boolean,\n lazyLoadQueue?: LazyLoadQueue,\n middleware?: Middleware,\n size?: PhotoSize | Extract<VideoSize, VideoSize.videoSize>,\n withoutPreloader?: boolean,\n loadPromises?: Promise<any>[],\n autoDownloadSize?: number,\n noBlur?: boolean,\n noThumb?: boolean,\n noFadeIn?: boolean,\n blurAfter?: boolean,\n managers?: AppManagers,\n processUrl?: (url: string) => Promise<string>\n}) {\n const ret = {\n loadPromises: {\n thumb: Promise.resolve() as Promise<any>,\n full: Promise.resolve() as Promise<any>\n },\n images: {\n thumb: null as HTMLImageElement | HTMLCanvasElement,\n full: null as HTMLVideoElement | HTMLImageElement\n },\n preloader: null as ProgressivePreloader,\n aspecter: null as HTMLElement\n };\n\n const isDocument = photo._ === 'document';\n const isImageFromDocument = isDocument && photo.mime_type.startsWith('image/') && !size;\n const isWebDoc = isWebDocument(photo);\n if(!((photo as MyPhoto).sizes || (photo as MyDocument).thumbs) && !isWebDoc && !isImageFromDocument) {\n if(boxWidth && boxHeight && !size && isDocument) {\n setAttachmentSize(photo, container, boxWidth, boxHeight, undefined, message);\n }\n\n return ret;\n }\n\n let noAutoDownload = autoDownloadSize === 0;\n\n if(!size) {\n if(boxWidth === undefined) boxWidth = mediaSizes.active.regular.width;\n if(boxHeight === undefined) boxHeight = mediaSizes.active.regular.height;\n }\n\n container.classList.add('media-container');\n let aspecter = container;\n\n let isFit = true;\n let loadThumbPromise: Promise<any> = Promise.resolve();\n let thumbImage: HTMLImageElement | HTMLCanvasElement;\n // let image: HTMLImageElement;\n let cacheContext: ThumbCache;\n // if(withTail) {\n // image = wrapMediaWithTail(photo, message, container, boxWidth, boxHeight, isOut);\n // } else {\n\n if(boxWidth && boxHeight && !size) { // !album\n const set = setAttachmentSize(\n photo,\n container,\n boxWidth,\n boxHeight,\n undefined,\n message,\n undefined,\n isImageFromDocument ? {\n _: 'photoSize',\n w: photo.w,\n h: photo.h,\n size: photo.size,\n type: THUMB_TYPE_FULL\n } : undefined\n );\n size = set.photoSize;\n isFit = set.isFit;\n cacheContext = await managers.thumbsStorage.getCacheContext(photo, size.type);\n\n if(!isFit && !isWebDoc) {\n aspecter = document.createElement('div');\n aspecter.classList.add('media-container-aspecter');\n aspecter.style.width = set.size.width + 'px';\n aspecter.style.height = set.size.height + 'px';\n\n const gotThumb = getStrippedThumbIfNeeded(photo, cacheContext, !noBlur, true);\n if(gotThumb) {\n loadThumbPromise = gotThumb.loadPromise;\n const thumbImage = gotThumb.image; // local scope\n thumbImage.classList.add('media-photo');\n container.append(thumbImage);\n } else {\n const res = await wrapPhoto({\n container,\n message,\n photo,\n boxWidth: 0,\n boxHeight: 0,\n size,\n lazyLoadQueue,\n isOut,\n loadPromises,\n middleware,\n withoutPreloader,\n withTail,\n autoDownloadSize,\n noBlur,\n noThumb: true,\n blurAfter: true,\n managers\n // noFadeIn: true\n });\n const thumbImage = res.images.full;\n thumbImage.classList.add('media-photo', 'thumbnail');\n // container.append(thumbImage);\n }\n\n container.classList.add('media-container-fitted');\n container.append(aspecter);\n }\n } else {\n if(!size) {\n size = choosePhotoSize(photo, boxWidth, boxHeight, true);\n }\n\n cacheContext = await managers.thumbsStorage.getCacheContext(photo, size?.type);\n }\n\n if(!noThumb && !isWebDoc) {\n const gotThumb = getStrippedThumbIfNeeded(photo, cacheContext, !noBlur);\n if(gotThumb) {\n loadThumbPromise = Promise.all([loadThumbPromise, gotThumb.loadPromise]);\n ret.loadPromises.thumb = ret.loadPromises.full = loadThumbPromise;\n thumbImage = ret.images.thumb = gotThumb.image;\n thumbImage.classList.add('media-photo');\n aspecter.append(thumbImage);\n }\n }\n // }\n\n ret.aspecter = aspecter;\n\n if((size?._ === 'photoSizeEmpty' && isDocument) || (size as PhotoSize.photoStrippedSize)?.bytes) {\n return ret;\n }\n\n let media: HTMLVideoElement | HTMLImageElement;\n if(size?._ === 'videoSize') {\n media = ret.images.full = createVideo();\n media.autoplay = true;\n media.loop = true;\n media.muted = true;\n media.classList.add('media-photo');\n } else {\n media = ret.images.full = new Image();\n media.classList.add('media-photo');\n }\n\n // console.log('wrapPhoto downloaded:', photo, photo.downloaded, container);\n\n const needFadeIn = (thumbImage || !cacheContext.downloaded) && liteMode.isAvailable('animations') && !noFadeIn;\n\n let preloader: ProgressivePreloader;\n const uploadingFileName = (message as Message.message)?.uploadingFileName;\n if(!withoutPreloader) {\n if(!cacheContext.downloaded || uploadingFileName) {\n preloader = new ProgressivePreloader({\n attachMethod: 'prepend',\n isUpload: !!uploadingFileName\n });\n }\n\n if(uploadingFileName) { // means upload\n preloader.attachPromise(appDownloadManager.getUpload(uploadingFileName));\n preloader.attach(container);\n noAutoDownload = undefined;\n }\n }\n\n\n const getDownloadPromise = () => {\n // const promise = isGif && !size ?\n // managers.appDocsManager.downloadDoc(photo, /* undefined, */lazyLoadQueue?.queueId) :\n // managers.appPhotosManager.preloadPhoto(photo, size, lazyLoadQueue?.queueId, noAutoDownload);\n const haveToDownload = isImageFromDocument && !size;\n const promise = appDownloadManager.downloadMediaURL({\n media: photo,\n thumb: size,\n queueId: lazyLoadQueue?.queueId,\n onlyCache: haveToDownload ? undefined : noAutoDownload\n });\n\n return promise;\n };\n\n const renderOnLoad = (url: string) => {\n return renderMediaWithFadeIn(container, media, url, needFadeIn, aspecter, thumbImage);\n };\n\n const onLoad = async(url: string) => {\n if(middleware && !middleware()) return;\n\n if(processUrl) {\n url = await processUrl(url);\n }\n\n if(blurAfter) {\n const result = blur(url, 12);\n return result.promise.then(() => {\n // image = result.canvas;\n return renderOnLoad(result.canvas.toDataURL());\n });\n }\n\n return renderOnLoad(url);\n };\n\n let loadPromise: Promise<any>;\n const canAttachPreloader = (\n (size as PhotoSize.photoSize).w >= 150 &&\n (size as PhotoSize.photoSize).h >= 150\n ) || noAutoDownload;\n const load = async() => {\n if(noAutoDownload && !withoutPreloader && preloader) {\n preloader.construct();\n preloader.setManual();\n }\n\n const promise = getDownloadPromise();\n const cacheContext = await managers.thumbsStorage.getCacheContext(photo, size?.type);\n if(\n preloader &&\n !cacheContext.downloaded &&\n !withoutPreloader &&\n canAttachPreloader\n ) {\n preloader.attach(container, false, promise);\n }\n\n noAutoDownload = undefined;\n\n const renderPromise = promise.then(onLoad);\n renderPromise.catch(noop);\n return {download: promise, render: renderPromise};\n };\n\n if(preloader) {\n preloader.setDownloadFunction(load);\n }\n\n if(cacheContext.downloaded) {\n loadThumbPromise = loadPromise = (await load()).render;\n } else {\n if(!lazyLoadQueue) loadPromise = (await load()).render;\n /* else if(noAutoDownload) {\n preloader.construct();\n preloader.setManual();\n preloader.attach(container);\n } */ else lazyLoadQueue.push({div: container, load: () => load().then(({download}) => download)});\n }\n\n if(loadPromises && loadThumbPromise) {\n loadPromises.push(loadThumbPromise);\n }\n\n // const perf = performance.now();\n await loadThumbPromise;\n ret.loadPromises.thumb = loadThumbPromise;\n ret.loadPromises.full = loadPromise || Promise.resolve();\n ret.preloader = preloader;\n\n // const elapsedTime = performance.now() - perf;\n // if(elapsedTime > 4) {\n // console.log('wrapping photo thumb time', elapsedTime, photo, size);\n // }\n\n return ret;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {hexToRgb} from '../../helpers/color';\nimport {Message} from '../../layer';\nimport getPeerColorById from '../../lib/appManagers/utils/peers/getPeerColorById';\nimport {AnimationItemGroup} from '../animationIntersector';\nimport ReplyContainer from '../chat/replyContainer';\n\nexport default function wrapReply(\n title: Parameters<ReplyContainer['fill']>[0],\n subtitle: Parameters<ReplyContainer['fill']>[1],\n animationGroup: AnimationItemGroup,\n message?: Message.message | Message.messageService,\n setColorPeerId?: PeerId\n) {\n const replyContainer = new ReplyContainer('reply', animationGroup);\n const fillPromise = replyContainer.fill(title, subtitle, message);\n\n if(setColorPeerId) {\n const hex = getPeerColorById(setColorPeerId, false);\n const [r, g, b] = hexToRgb(hex);\n replyContainer.container.style.setProperty('--override-color', `${r}, ${g}, ${b}`);\n replyContainer.container.classList.add('is-overriding-color');\n // replyContainer.border.style.backgroundColor = hex;\n // replyContainer.title.style.color = hex;\n }\n\n return {container: replyContainer.container, fillPromise};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MyMessage} from '../../lib/appManagers/appMessagesManager';\nimport getMessageSenderPeerIdOrName from '../../lib/appManagers/utils/messages/getMessageSenderPeerIdOrName';\nimport {i18n} from '../../lib/langPack';\nimport rootScope from '../../lib/rootScope';\nimport wrapPeerTitle from './peerTitle';\n\nexport default async function wrapSenderToPeer(message: MyMessage) {\n const senderTitle: HTMLElement = document.createElement('span');\n senderTitle.classList.add('sender-title');\n\n const fromMe = message.fromId === rootScope.myId && message.peerId !== rootScope.myId;\n senderTitle.append(\n fromMe ?\n i18n('FromYou') :\n await wrapPeerTitle({\n ...getMessageSenderPeerIdOrName(message),\n dialog: message.peerId === rootScope.myId\n })\n );\n\n if(await rootScope.managers.appPeersManager.isAnyGroup(message.peerId) || fromMe) {\n const peerTitle = await wrapPeerTitle({peerId: message.peerId});\n senderTitle.append(' ➝ ', peerTitle);\n }\n\n return senderTitle;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {formatDateAccordingToTodayNew} from '../../helpers/date';\nimport {MyMessage} from '../../lib/appManagers/appMessagesManager';\n\nexport default function wrapSentTime(message: MyMessage) {\n const el: HTMLElement = document.createElement('span');\n el.classList.add('sent-time');\n el.append(formatDateAccordingToTodayNew(new Date(message.date * 1000)));\n\n return el;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_WEBP_SUPPORTED from '../../environment/webpSupport';\nimport assumeType from '../../helpers/assumeType';\nimport getPathFromBytes from '../../helpers/bytes/getPathFromBytes';\nimport deferredPromise from '../../helpers/cancellablePromise';\nimport computeLockColor from '../../helpers/computeLockColor';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport createVideo from '../../helpers/dom/createVideo';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport renderImageFromUrl, {renderImageFromUrlPromise} from '../../helpers/dom/renderImageFromUrl';\nimport getImageFromStrippedThumb from '../../helpers/getImageFromStrippedThumb';\nimport getPreviewURLFromThumb from '../../helpers/getPreviewURLFromThumb';\nimport makeError from '../../helpers/makeError';\nimport {makeMediaSize} from '../../helpers/mediaSize';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport {Middleware} from '../../helpers/middleware';\nimport onMediaLoad from '../../helpers/onMediaLoad';\nimport {isSavingLottiePreview, saveLottiePreview} from '../../helpers/saveLottiePreview';\nimport throttle from '../../helpers/schedulers/throttle';\nimport sequentialDom from '../../helpers/sequentialDom';\nimport {PhotoSize, VideoSize} from '../../layer';\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport appDownloadManager from '../../lib/appManagers/appDownloadManager';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getServerMessageId from '../../lib/appManagers/utils/messageId/getServerMessageId';\nimport choosePhotoSize from '../../lib/appManagers/utils/photos/choosePhotoSize';\nimport getStickerEffectThumb from '../../lib/appManagers/utils/stickers/getStickerEffectThumb';\nimport lottieLoader from '../../lib/rlottie/lottieLoader';\nimport type RLottiePlayer from '../../lib/rlottie/rlottiePlayer';\nimport rootScope from '../../lib/rootScope';\nimport type {ThumbCache} from '../../lib/storages/thumbs';\nimport webpWorkerController from '../../lib/webp/webpWorkerController';\nimport {Awaited, SendMessageEmojiInteractionData} from '../../types';\nimport {getEmojiToneIndex} from '../../vendor/emoji';\nimport animationIntersector, {AnimationItemGroup} from '../animationIntersector';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport PopupStickers from '../popups/stickers';\nimport {hideToast, toastNew} from '../toast';\nimport wrapStickerAnimation from './stickerAnimation';\nimport framesCache from '../../helpers/framesCache';\nimport {IS_MOBILE} from '../../environment/userAgent';\nimport liteMode, {LiteModeKey} from '../../helpers/liteMode';\nimport PopupElement from '../popups';\n\n// https://github.com/telegramdesktop/tdesktop/blob/master/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp#L40\nexport const STICKER_EFFECT_MULTIPLIER = 1 + 0.245 * 2;\nconst EMOJI_EFFECT_MULTIPLIER = 3;\n\nconst locksUrls: {[docId: string]: string} = {};\n\nexport const videosCache: {[key: string]: Promise<any>} = {};\n\nconst onAnimationEnd = (element: HTMLElement, onAnimationEnd: () => void, timeout: number) => {\n const onEnd = () => {\n element.removeEventListener('animationend', onEnd);\n onAnimationEnd();\n clearTimeout(_timeout);\n };\n element.addEventListener('animationend', onEnd);\n const _timeout = setTimeout(onEnd, timeout);\n};\n\nexport default async function wrapSticker({doc, div, middleware, loadStickerMiddleware, lazyLoadQueue, exportLoad, group, play, onlyThumb, emoji, width, height, withThumb, loop, loadPromises, needFadeIn, needUpscale, skipRatio, static: asStatic, managers = rootScope.managers, fullThumb, isOut, noPremium, withLock, relativeEffect, loopEffect, isCustomEmoji, syncedVideo, liteModeKey, isEffect}: {\n doc: MyDocument,\n div: HTMLElement | HTMLElement[],\n middleware?: Middleware,\n loadStickerMiddleware?: Middleware,\n lazyLoadQueue?: LazyLoadQueue,\n exportLoad?: number,\n group?: AnimationItemGroup,\n play?: boolean,\n onlyThumb?: boolean,\n emoji?: string,\n width?: number,\n height?: number,\n withThumb?: boolean,\n loop?: RLottiePlayer['loop'],\n loadPromises?: Promise<any>[],\n needFadeIn?: boolean,\n needUpscale?: boolean,\n skipRatio?: number,\n static?: boolean,\n managers?: AppManagers,\n fullThumb?: PhotoSize | Extract<VideoSize, VideoSize.videoSize>,\n isOut?: boolean,\n noPremium?: boolean,\n withLock?: boolean,\n relativeEffect?: boolean,\n loopEffect?: boolean,\n isCustomEmoji?: boolean,\n syncedVideo?: boolean,\n liteModeKey?: LiteModeKey | false,\n isEffect?: boolean\n}) {\n div = Array.isArray(div) ? div : [div];\n\n liteModeKey ??= 'stickers_panel';\n\n if(isCustomEmoji) {\n emoji = doc.stickerEmojiRaw;\n }\n\n const stickerType = doc.sticker;\n if(stickerType === 1) {\n asStatic = true;\n }\n\n if(!width && !height) {\n const sizes = mediaSizes.active;\n const boxSize = emoji ? sizes.emojiSticker : (doc.animated ? sizes.animatedSticker : sizes.staticSticker);\n const size = makeMediaSize(doc.w, doc.h).aspectFitted(boxSize);\n width = size.width;\n height = size.height;\n }\n\n if(stickerType === 2) {\n // LottieLoader.loadLottie();\n lottieLoader.loadLottieWorkers();\n }\n\n loop = !!(!emoji || isCustomEmoji) && loop;\n\n div.forEach((div) => {\n div.dataset.docId = '' + doc.id;\n if(emoji) {\n div.dataset.stickerEmoji = emoji;\n }\n\n div.dataset.stickerPlay = '' + +(play || false);\n div.dataset.stickerLoop = '' + +(loop || false);\n\n div.classList.add('media-sticker-wrapper');\n });\n\n if(play && !liteMode.isAvailable(liteModeKey) && !isCustomEmoji && !isEffect) {\n play = false;\n loop = false;\n }\n\n /* if(stickerType === 3) {\n const videoRes = wrapVideo({\n doc,\n boxWidth: width,\n boxHeight: height,\n container: div,\n group,\n lazyLoadQueue,\n middleware,\n withoutPreloader: true,\n loadPromises,\n noPlayButton: true,\n noInfo: true\n });\n\n if(videoRes.thumb) {\n if(videoRes.thumb.images.thumb) {\n videoRes.thumb.images.thumb.classList.add('media-sticker', 'thumbnail');\n }\n\n if(videoRes.thumb.images.full) {\n videoRes.thumb.images.full.classList.add('media-sticker');\n }\n }\n\n return videoRes.loadPromise;\n } */\n\n // console.log('wrap sticker', doc, div, onlyThumb);\n\n let cacheContext: ThumbCache;\n const getCacheContext = async(type: string = cacheContext?.type) => {\n return cacheContext = await managers.thumbsStorage.getCacheContext(doc, type);\n };\n\n const isAnimated = !asStatic && (stickerType === 2 || stickerType === 3);\n\n const effectThumb = getStickerEffectThumb(doc);\n if(isOut !== undefined && effectThumb && !isOut) {\n div.forEach((div) => div.classList.add('reflect-x'));\n }\n\n const willHaveLock = effectThumb && withLock;\n if(willHaveLock) {\n const lockUrl = locksUrls[doc.id];\n div.forEach((div) => {\n div.classList.add('is-premium-sticker', 'tgico-premium_lock');\n lockUrl && div.style.setProperty('--lock-url', `url(${lockUrl})`);\n });\n }\n\n if(asStatic && stickerType !== 1) {\n const thumb = choosePhotoSize(doc, width, height, false) as PhotoSize.photoSize;\n await getCacheContext(thumb.type);\n } else {\n await getCacheContext(fullThumb?.type);\n }\n\n const toneIndex = emoji && !isCustomEmoji ? getEmojiToneIndex(emoji) : -1;\n const downloaded = cacheContext.downloaded && !needFadeIn;\n\n const isThumbNeededForType = isAnimated;\n const lottieCachedThumb = stickerType === 2 || stickerType === 3 ? await managers.appDocsManager.getLottieCachedThumb(doc.id, toneIndex) : undefined;\n\n const ret = {render: undefined as typeof loadPromise, load: undefined as typeof load};\n let loadThumbPromise = deferredPromise<void>();\n let haveThumbCached = false;\n if((\n doc.thumbs?.length ||\n lottieCachedThumb\n ) &&\n !div[0].firstElementChild && (\n !downloaded ||\n isThumbNeededForType ||\n onlyThumb\n ) && withThumb !== false/* && doc.thumbs[0]._ !== 'photoSizeEmpty' */\n ) {\n let thumb = lottieCachedThumb || doc.thumbs[0];\n\n // console.log('wrap sticker', thumb, div);\n\n const afterRender = (div: HTMLElement, thumbImage: HTMLElement) => {\n if(!div.childElementCount) {\n sequentialDom.mutateElement(div, () => {\n if(!div.childElementCount) {\n thumbImage.classList.add('media-sticker', 'thumbnail');\n div.append(thumbImage);\n }\n\n loadThumbPromise.resolve();\n });\n } else {\n loadThumbPromise.resolve();\n }\n };\n\n if('url' in thumb) {\n haveThumbCached = true;\n div.forEach((div) => {\n const thumbImage = new Image();\n renderImageFromUrl(thumbImage, (thumb as any).url, () => afterRender(div, thumbImage));\n });\n } else if('bytes' in thumb) {\n if(thumb._ === 'photoPathSize') {\n if(!thumb.bytes.length) {\n thumb = doc.thumbs.find((t) => (t as PhotoSize.photoStrippedSize).bytes?.length) || thumb;\n }\n\n const d = getPathFromBytes((thumb as PhotoSize.photoStrippedSize).bytes);\n const ns = 'http://www.w3.org/2000/svg';\n const svg = document.createElementNS(ns, 'svg');\n svg.classList.add('rlottie-vector', 'media-sticker', 'thumbnail');\n svg.setAttributeNS(null, 'viewBox', `0 0 ${doc.w || 512} ${doc.h || 512}`);\n\n // const defs = document.createElementNS(ns, 'defs');\n // const linearGradient = document.createElementNS(ns, 'linearGradient');\n // linearGradient.setAttributeNS(null, 'id', 'g');\n // linearGradient.setAttributeNS(null, 'x1', '-300%');\n // linearGradient.setAttributeNS(null, 'x2', '-200%');\n // linearGradient.setAttributeNS(null, 'y1', '0');\n // linearGradient.setAttributeNS(null, 'y2', '0');\n // const stops = [\n // ['-10%', '.1'],\n // ['30%', '.07'],\n // ['70%', '.07'],\n // ['110%', '.1']\n // ].map(([offset, stopOpacity]) => {\n // const stop = document.createElementNS(ns, 'stop');\n // stop.setAttributeNS(null, 'offset', offset);\n // stop.setAttributeNS(null, 'stop-opacity', stopOpacity);\n // return stop;\n // });\n // const animates = [\n // ['-300%', '1200%'],\n // ['-200%', '1300%']\n // ].map(([from, to], idx) => {\n // const animate = document.createElementNS(ns, 'animate');\n // animate.setAttributeNS(null, 'attributeName', 'x' + (idx + 1));\n // animate.setAttributeNS(null, 'from', from);\n // animate.setAttributeNS(null, 'to', to);\n // animate.setAttributeNS(null, 'dur', '3s');\n // animate.setAttributeNS(null, 'repeatCount', 'indefinite');\n // return animate;\n // });\n // linearGradient.append(...stops, ...animates);\n // defs.append(linearGradient);\n // svg.append(defs);\n\n const path = document.createElementNS(ns, 'path');\n path.setAttributeNS(null, 'd', d);\n if(liteMode.isAvailable('animations') && !isCustomEmoji) path.setAttributeNS(null, 'fill', 'url(#g)');\n svg.append(path);\n div.forEach((div, idx) => div.append(idx > 0 ? svg.cloneNode(true) : svg));\n haveThumbCached = true;\n loadThumbPromise.resolve();\n } else if(toneIndex <= 0) {\n const r = () => {\n (div as HTMLElement[]).forEach((div) => {\n const thumbImage = new Image();\n const url = getPreviewURLFromThumb(doc, thumb as PhotoSize.photoStrippedSize, true);\n renderImageFromUrl(thumbImage, url, () => afterRender(div, thumbImage));\n });\n };\n\n if((IS_WEBP_SUPPORTED || doc.pFlags.stickerThumbConverted || cacheContext.url)/* && false */) {\n haveThumbCached = true;\n r();\n } else {\n haveThumbCached = true;\n webpWorkerController.convert('main-' + doc.id, thumb.bytes).then((bytes) => {\n managers.appDocsManager.saveWebPConvertedStrippedThumb(doc.id, bytes);\n (thumb as PhotoSize.photoStrippedSize).bytes = bytes;\n doc.pFlags.stickerThumbConverted = true;\n\n if((middleware && !middleware()) || (div as HTMLElement[])[0].childElementCount) {\n loadThumbPromise.resolve();\n return;\n }\n\n r();\n }).catch(() => loadThumbPromise.resolve());\n }\n }\n } else if(((stickerType === 2 && toneIndex <= 0) || stickerType === 3) && (withThumb || onlyThumb)) {\n const load = async() => {\n if((div as HTMLElement[])[0].childElementCount || (middleware && !middleware())) {\n loadThumbPromise.resolve();\n return;\n }\n\n const r = (div: HTMLElement, thumbImage: HTMLElement, url: string) => {\n if(div.childElementCount || (middleware && !middleware())) {\n loadThumbPromise.resolve();\n return;\n }\n\n if(!url) afterRender(div, thumbImage);\n else renderImageFromUrl(thumbImage, url, () => afterRender(div, thumbImage));\n };\n\n await getCacheContext();\n (div as HTMLElement[]).forEach((div) => {\n if(cacheContext.url) {\n r(div, new Image(), cacheContext.url);\n } else if('bytes' in thumb) {\n const res = getImageFromStrippedThumb(doc, thumb as PhotoSize.photoStrippedSize, true);\n res.loadPromise.then(() => r(div, res.image, ''));\n\n // return managers.appDocsManager.getThumbURL(doc, thumb as PhotoSize.photoStrippedSize).promise.then(r);\n } else {\n appDownloadManager.downloadMediaURL({\n media: doc,\n thumb: thumb as PhotoSize\n }).then(async(url) => {\n return r(div, new Image(), url);\n });\n }\n });\n };\n\n if(lazyLoadQueue && onlyThumb) {\n lazyLoadQueue.push({div: div[0], load});\n loadThumbPromise.resolve();\n return ret;\n } else {\n load();\n\n if((thumb as any).url) {\n haveThumbCached = true;\n }\n }\n }\n }\n\n if(loadPromises && haveThumbCached) {\n loadPromises.push(loadThumbPromise);\n }\n\n if(onlyThumb/* || true */) { // for sticker panel\n return ret;\n }\n\n const middlewareError = makeError('MIDDLEWARE');\n const load = async() => {\n if(middleware && !middleware()) {\n throw middlewareError;\n }\n\n if(stickerType === 2 && !asStatic) {\n const blob = await appDownloadManager.downloadMedia({media: doc, queueId: lazyLoadQueue?.queueId, thumb: fullThumb});\n if(middleware && !middleware()) {\n throw middlewareError;\n }\n\n const animation = await lottieLoader.loadAnimationWorker({\n container: (div as HTMLElement[])[0],\n loop,\n autoplay: play,\n animationData: blob,\n width,\n height,\n name: 'doc' + doc.id,\n needUpscale,\n skipRatio,\n toneIndex,\n sync: isCustomEmoji,\n middleware: loadStickerMiddleware ?? middleware,\n group,\n liteModeKey: liteModeKey || undefined\n });\n\n // const deferred = deferredPromise<void>();\n\n const setLockColor = willHaveLock ? () => {\n const lockUrl = locksUrls[doc.id] ??= computeLockColor(animation.canvas[0]);\n (div as HTMLElement[]).forEach((div) => div.style.setProperty('--lock-url', `url(${lockUrl})`));\n } : undefined;\n\n const onFirstFrame = (container: HTMLElement, canvas: HTMLCanvasElement) => {\n const element = container.firstElementChild !== canvas && container.firstElementChild as HTMLElement;\n if(needFadeIn !== false) {\n needFadeIn = (needFadeIn || !element || element.tagName === 'svg') && liteMode.isAvailable('animations');\n }\n\n const cb = () => {\n if(element && element !== canvas && element.tagName !== 'DIV') {\n element.remove();\n }\n };\n\n if(!needFadeIn) {\n if(element) {\n sequentialDom.mutate(cb);\n }\n } else {\n sequentialDom.mutate(() => {\n canvas && canvas.classList.add('fade-in');\n if(element) {\n element.classList.add('fade-out');\n }\n\n onAnimationEnd(canvas || element, () => {\n sequentialDom.mutate(() => {\n canvas && canvas.classList.remove('fade-in');\n cb();\n });\n }, 400);\n });\n }\n };\n\n animation.addEventListener('firstFrame', () => {\n const canvas = animation.canvas[0];\n if(withThumb !== false || isCustomEmoji) {\n saveLottiePreview(doc, canvas, toneIndex);\n }\n\n if(willHaveLock) {\n setLockColor();\n }\n\n if(!isCustomEmoji) {\n (div as HTMLElement[]).forEach((container, idx) => {\n onFirstFrame(container, animation.canvas[idx]);\n });\n }\n }, {once: true});\n\n if(emoji) {\n managers.appStickersManager.preloadAnimatedEmojiStickerAnimation(emoji);\n }\n\n return animation;\n\n // return deferred;\n // await new Promise((resolve) => setTimeout(resolve, 5e3));\n } else if(asStatic || stickerType === 3) {\n const isSingleVideo = isAnimated && syncedVideo;\n const cacheName = isSingleVideo ? framesCache.generateName('' + doc.id, 0, 0, undefined, undefined) : undefined;\n\n const cachePromise = videosCache[cacheName];\n if(cachePromise) {\n return cachePromise as typeof promise;\n }\n\n const d = isSingleVideo ? (div as HTMLElement[]).slice(0, 1) : div as HTMLElement[];\n const media: HTMLElement[] = d.map(() => {\n let media: HTMLElement;\n if(asStatic) {\n media = new Image();\n } else {\n const video = media = createVideo();\n video.muted = true;\n if(play) video.autoplay = true;\n if(loop) video.loop = true;\n\n if(loop && typeof(loop) === 'number') {\n let previousTime = 0, playedTimes = 0;\n function onTimeupdate(this: HTMLVideoElement) {\n if(previousTime > this.currentTime && ++playedTimes === loop as number) {\n this.autoplay = false;\n this.loop = false;\n this.pause();\n video.removeEventListener('timeupdate', onTimeupdate);\n }\n\n previousTime = this.currentTime;\n }\n\n video.addEventListener('timeupdate', onTimeupdate);\n }\n }\n\n media.classList.add('media-sticker');\n return media;\n });\n\n const thumbImage = (div as HTMLElement[]).map((div, idx) => (div.firstElementChild as HTMLElement) !== media[idx] && div.firstElementChild) as HTMLElement[];\n if(needFadeIn !== false) {\n needFadeIn = (needFadeIn || !downloaded || (asStatic ? thumbImage[0] : (!thumbImage[0] || thumbImage[0].tagName === 'svg'))) && liteMode.isAvailable('animations');\n }\n\n if(needFadeIn) {\n media.forEach((media) => media.classList.add('fade-in'));\n }\n\n const promise = new Promise<HTMLVideoElement[] | HTMLImageElement[]>(async(resolve, reject) => {\n const r = async() => {\n if(middleware && !middleware()) {\n reject(middlewareError);\n return;\n }\n\n const mediaLength = media.length;\n const loaded: HTMLElement[] = [];\n const onLoad = (div: HTMLElement, media: HTMLElement, thumbImage: HTMLElement) => {\n sequentialDom.mutateElement(div, () => {\n if(middleware && !middleware()) {\n reject(middlewareError);\n return;\n }\n\n if(!media) {\n if(!isSingleVideo || !isAnimated) {\n thumbImage?.remove();\n }\n\n return;\n }\n\n if(media as HTMLVideoElement) {\n const w = width * window.devicePixelRatio;\n const h = height * window.devicePixelRatio;\n if(!isSavingLottiePreview(doc, toneIndex, w, h)) {\n // const perf = performance.now();\n const canvas = document.createElement('canvas');\n canvas.width = w;\n canvas.height = h;\n const ctx = canvas.getContext('2d');\n ctx.drawImage(media as HTMLVideoElement, 0, 0, canvas.width, canvas.height);\n saveLottiePreview(doc, canvas, toneIndex);\n // console.log('perf', performance.now() - perf);\n }\n }\n\n if(isSingleVideo) {\n resolve(media as any);\n return;\n }\n\n div.append(media);\n\n if(needFadeIn) {\n thumbImage && thumbImage.classList.add('fade-out');\n onAnimationEnd(media, () => {\n media.classList.remove('fade-in');\n thumbImage?.remove();\n }, 400);\n } else {\n thumbImage?.remove();\n }\n\n if(isAnimated) {\n animationIntersector.addAnimation({\n animation: media as HTMLVideoElement,\n observeElement: div,\n group,\n controlled: middleware,\n liteModeKey: liteModeKey || undefined\n });\n }\n\n if(loaded.push(media) === mediaLength) {\n resolve(loaded as any);\n }\n });\n };\n\n await getCacheContext();\n let lastPromise: Promise<any>;\n (div as HTMLElement[]).forEach((div, idx) => {\n const _media = media[idx];\n const cb = () => onLoad(div, _media, thumbImage[idx]);\n if(_media) lastPromise = renderImageFromUrlPromise(_media, cacheContext.url);\n lastPromise.then(cb);\n });\n };\n\n await getCacheContext();\n if(cacheContext.url) r();\n else {\n let promise: Promise<any>;\n if(stickerType !== 1 && asStatic) {\n const thumb = choosePhotoSize(doc, width, height, false) as PhotoSize.photoSize;\n // promise = managers.appDocsManager.getThumbURL(doc, thumb).promise\n promise = appDownloadManager.downloadMediaURL({media: doc, thumb, queueId: lazyLoadQueue?.queueId});\n } else {\n promise = appDownloadManager.downloadMediaURL({media: doc, queueId: lazyLoadQueue?.queueId});\n }\n\n promise.then(r, reject);\n }\n });\n\n if(cacheName) {\n videosCache[cacheName] = promise as any;\n loadStickerMiddleware && promise.finally(() => {\n if(!loadStickerMiddleware()) {\n delete videosCache[cacheName];\n }\n });\n }\n\n return promise;\n }\n };\n\n if(exportLoad && ((exportLoad === 1 && (!downloaded || isAnimated)) || exportLoad === 2)) {\n ret.load = load;\n return ret;\n }\n\n const loadPromise: Promise<Awaited<ReturnType<typeof load>> | void> = lazyLoadQueue && (!downloaded || isAnimated) ?\n (lazyLoadQueue.push({div: div[0], load}), Promise.resolve()) :\n load();\n\n if(downloaded && (asStatic/* || stickerType === 3 */)) {\n loadThumbPromise = loadPromise as any;\n if(loadPromises) {\n loadPromises.push(loadThumbPromise);\n }\n }\n\n if(stickerType === 2 && effectThumb && isOut !== undefined && !noPremium) {\n attachStickerEffectHandler({\n container: div[0],\n doc,\n managers,\n middleware,\n isOut,\n width,\n loadPromise,\n relativeEffect,\n loopEffect\n });\n }\n\n ret.render = loadPromise as any;\n return ret;\n}\n\nfunction attachStickerEffectHandler({container, doc, managers, middleware, isOut, width, loadPromise, relativeEffect, loopEffect}: {\n container: HTMLElement,\n doc: MyDocument,\n managers: AppManagers,\n middleware: Middleware,\n isOut: boolean,\n width: number,\n loadPromise: Promise<any>,\n relativeEffect?: boolean,\n loopEffect?: boolean\n}) {\n managers.appStickersManager.preloadSticker(doc.id, true);\n\n let playing = false;\n attachClickEvent(container, async(e) => {\n const isAvailable = liteMode.isAvailable('effects_premiumstickers') || relativeEffect;\n cancelEvent(e);\n if(!e.isTrusted && !isAvailable) {\n return;\n }\n\n if(playing || !isAvailable) {\n const a = document.createElement('a');\n a.onclick = () => {\n hideToast();\n PopupElement.createPopup(PopupStickers, doc.stickerSetInput).show();\n };\n\n toastNew({\n langPackKey: 'Sticker.Premium.Click.Info',\n langPackArguments: [a]\n });\n\n return;\n }\n\n playing = true;\n\n await loadPromise;\n const {animationDiv, stickerPromise} = wrapStickerAnimation({\n doc,\n middleware,\n side: isOut ? 'right' : 'left',\n size: width * STICKER_EFFECT_MULTIPLIER,\n target: container,\n play: true,\n fullThumb: getStickerEffectThumb(doc),\n relativeEffect,\n loopEffect\n });\n\n if(isOut !== undefined && !isOut/* && !relativeEffect */) {\n animationDiv.classList.add('reflect-x');\n }\n\n stickerPromise.then((player) => {\n player.addEventListener('destroy', () => {\n playing = false;\n });\n });\n });\n}\n\nexport async function onEmojiStickerClick({event, container, managers, peerId, middleware}: {\n event: Event,\n container: HTMLElement,\n managers: AppManagers,\n peerId: PeerId,\n middleware: Middleware\n}) {\n cancelEvent(event);\n\n const bubble = findUpClassName(container, 'bubble');\n const emoji = container.dataset.stickerEmoji;\n\n const animation = !container.classList.contains('custom-emoji') ? lottieLoader.getAnimation(container) : undefined;\n if(animation?.paused) {\n const doc = await managers.appStickersManager.getAnimatedEmojiSoundDocument(emoji);\n if(doc) {\n const audio = document.createElement('audio');\n audio.style.display = 'none';\n container.parentElement.append(audio);\n\n try {\n const url = await appDownloadManager.downloadMediaURL({media: doc});\n\n audio.src = url;\n audio.play();\n await onMediaLoad(audio, undefined, true);\n\n audio.addEventListener('ended', () => {\n audio.src = '';\n audio.remove();\n }, {once: true});\n } catch(err) {\n\n }\n }\n\n animation.autoplay = true;\n animation.restart();\n }\n\n if(!peerId.isUser() || !liteMode.isAvailable('effects_emoji')) {\n return;\n }\n\n const activeAnimations: Set<{}> = (container as any).activeAnimations ??= new Set();\n if(activeAnimations.size >= 3) {\n return;\n }\n\n const doc = await managers.appStickersManager.getAnimatedEmojiSticker(emoji, true);\n if(!doc) {\n return;\n }\n\n const data: SendMessageEmojiInteractionData = (container as any).emojiData ??= {\n a: [],\n v: 1\n };\n\n const sendInteractionThrottled: () => void = (container as any).sendInteractionThrottled ??= throttle(() => {\n const length = data.a.length;\n if(!length) {\n return;\n }\n\n const firstTime = data.a[0].t;\n\n data.a.forEach((a) => {\n a.t = (a.t - firstTime) / 1000;\n });\n\n const bubble = findUpClassName(container, 'bubble');\n managers.appMessagesManager.setTyping(appImManager.chat.peerId, {\n _: 'sendMessageEmojiInteraction',\n msg_id: getServerMessageId(+bubble.dataset.mid),\n emoticon: emoji,\n interaction: {\n _: 'dataJSON',\n data: JSON.stringify(data)\n }\n }, true, appImManager.chat.threadId);\n\n data.a.length = 0;\n }, 1000, false);\n\n const o = {};\n activeAnimations.add(o);\n\n const isOut = bubble ? bubble.classList.contains('is-out') : undefined;\n const {animationDiv} = wrapStickerAnimation({\n doc,\n middleware,\n side: isOut ? 'right' : 'left',\n size: 360,\n target: container,\n play: true,\n withRandomOffset: true,\n onUnmount: () => {\n activeAnimations.delete(o);\n }\n });\n\n if(isOut !== undefined && !isOut) {\n animationDiv.classList.add('reflect-x');\n }\n\n // using a trick here: simulated event from interlocutor's interaction won't fire ours\n if(event.isTrusted) {\n data.a.push({\n i: 1,\n t: Date.now()\n });\n\n sendInteractionThrottled();\n }\n // });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n/**\n * https://core.telegram.org/api/files#vector-thumbnails\n */\nexport default function getPathFromBytes(bytes: Uint8Array) {\n const lookup = 'AACAAAAHAAALMAAAQASTAVAAAZaacaaaahaaalmaaaqastava.az0123456789-,';\n\n let path = 'M';\n for(let i = 0, length = bytes.length; i < length; ++i) {\n const num = bytes[i];\n\n if(num >= (128 + 64)) {\n path += lookup[num - 128 - 64];\n } else {\n if(num >= 128) {\n path += ',';\n } else if(num >= 64) {\n path += '-';\n }\n path += '' + (num & 63);\n }\n }\n path += 'z';\n\n return path;\n}\n","// https://github.com/telegramdesktop/tdesktop/blob/543bfab24a76402992421063f1e6444f347d31fe/Telegram/SourceFiles/boxes/sticker_set_box.cpp#L75\nexport default function computeLockColor(canvas: HTMLCanvasElement) {\n const context = canvas.getContext('2d');\n const size = 20 * (canvas.dpr ?? 1);\n const width = size;\n const height = size;\n const skipx = (canvas.width - width) / 2;\n const margin = 0/* * (canvas.dpr ?? 1) */;\n const skipy = canvas.height - height - margin;\n const imageData = context.getImageData(skipx, skipy, width, height).data;\n let sr = 0, sg = 0, sb = 0, sa = 0;\n for(let i = 0; i < imageData.length; i += 4) {\n sr += imageData[i];\n sg += imageData[i + 1];\n sb += imageData[i + 2];\n sa += imageData[i + 3];\n }\n\n const outCanvas = document.createElement('canvas');\n outCanvas.width = size;\n outCanvas.height = size;\n const outContext = outCanvas.getContext('2d');\n const color = new Uint8ClampedArray([sr * 255 / sa, sg * 255 / sa, sb * 255 / sa, 255]);\n const rgba = `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${color[3]})`;\n outContext.fillStyle = rgba;\n outContext.fillRect(0, 0, outCanvas.width, outCanvas.height);\n outContext.fillStyle = `rgba(112, 117, 121, 0.3)`;\n outContext.fillRect(0, 0, outCanvas.width, outCanvas.height);\n // document.querySelector('.popup-title').append(c);\n return outCanvas.toDataURL('image/jpeg');\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_VIBRATE_SUPPORTED from '../../environment/vibrateSupport';\nimport assumeType from '../../helpers/assumeType';\nimport isInDOM from '../../helpers/dom/isInDOM';\nimport makeError from '../../helpers/makeError';\nimport {getMiddleware, Middleware} from '../../helpers/middleware';\nimport throttleWithRaf from '../../helpers/schedulers/throttleWithRaf';\nimport windowSize from '../../helpers/windowSize';\nimport {PhotoSize, VideoSize} from '../../layer';\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport RLottiePlayer from '../../lib/rlottie/rlottiePlayer';\nimport wrapSticker from './sticker';\n\nexport default function wrapStickerAnimation({\n size,\n doc,\n middleware,\n target,\n side,\n skipRatio,\n play,\n managers,\n fullThumb,\n withRandomOffset,\n relativeEffect,\n loopEffect,\n onUnmount\n}: {\n size: number,\n doc: MyDocument,\n middleware?: Middleware,\n target: HTMLElement,\n side: 'left' | 'center' | 'right',\n skipRatio?: number,\n play: boolean,\n managers?: AppManagers,\n fullThumb?: PhotoSize | Extract<VideoSize, VideoSize.videoSize>,\n withRandomOffset?: boolean,\n relativeEffect?: boolean,\n loopEffect?: boolean,\n onUnmount?: () => void\n}) {\n const animationDiv = document.createElement('div');\n animationDiv.classList.add('emoji-animation');\n\n // const size = 280;\n animationDiv.style.width = size + 'px';\n animationDiv.style.height = size + 'px';\n\n let animation: RLottiePlayer;\n const unmountAnimation = () => {\n middlewareHelper.clean();\n animation?.remove();\n animationDiv.remove();\n appImManager.chat.bubbles.scrollable.container.removeEventListener('scroll', onScroll);\n onUnmount?.();\n };\n\n const middlewareHelper = middleware?.create() ?? getMiddleware();\n middleware = middlewareHelper.get();\n\n const stickerPromise = wrapSticker({\n div: animationDiv,\n doc,\n middleware,\n withThumb: false,\n needFadeIn: false,\n loop: !!loopEffect,\n width: size,\n height: size,\n play,\n group: 'none',\n skipRatio,\n managers,\n fullThumb,\n isEffect: true\n }).then(({render}) => render).then((_animation) => {\n assumeType<RLottiePlayer>(_animation);\n if(!middleware()) {\n _animation.remove();\n throw makeError('MIDDLEWARE');\n }\n\n animation = _animation;\n animation.addEventListener('enterFrame', (frameNo) => {\n if((!loopEffect && frameNo === animation.maxFrame) || !isInDOM(target)) {\n unmountAnimation();\n }\n });\n\n if(IS_VIBRATE_SUPPORTED) {\n animation.addEventListener('firstFrame', () => {\n navigator.vibrate(100);\n }, {once: true});\n }\n\n return animation;\n });\n\n const generateRandomSigned = (max: number) => {\n const r = Math.random() * max * 2;\n return r > max ? -r % max : r;\n };\n\n const randomOffsetX = withRandomOffset ? generateRandomSigned(16) : 0;\n const randomOffsetY = withRandomOffset ? generateRandomSigned(4) : 0;\n const setPosition = () => {\n if(!isInDOM(target)) {\n unmountAnimation();\n return;\n }\n\n const rect = target.getBoundingClientRect();\n\n const factor = rect.width / 200;\n const stableOffsetX = side === 'center' ? 0 : 16 * (side === 'right' ? 1 : -1) * factor;\n // const stableOffsetY = side === 'center' ? 0 : -50 * factor;\n const stableOffsetY = side === 'center' ? 0 : 0 * factor;\n\n const rectX = side === 'right' ? rect.right : rect.left;\n const rectY = rect.top;\n\n const addOffsetX = (side === 'center' ? (rect.width - size) / 2 : (side === 'right' ? -size : 0)) + stableOffsetX + randomOffsetX;\n const addOffsetY = (side === 'center' || true ? (rect.height - size) / 2 : 0) + stableOffsetY + randomOffsetY;\n const x = rectX + addOffsetX;\n const y = rectY + addOffsetY;\n\n if(y <= -size || y >= windowSize.height) {\n unmountAnimation();\n return;\n }\n\n if(relativeEffect) {\n if(side !== 'center') animationDiv.style[side] = Math.abs(stableOffsetX) * -1 + 'px';\n else animationDiv.style.left = addOffsetX + 'px';\n animationDiv.style.top = addOffsetY + 'px';\n } else {\n animationDiv.style.top = y + 'px';\n animationDiv.style.left = x + 'px';\n }\n };\n\n const onScroll = throttleWithRaf(setPosition);\n appImManager.chat.bubbles.scrollable.container.addEventListener('scroll', onScroll);\n\n setPosition();\n\n if(relativeEffect) {\n animationDiv.classList.add('is-relative');\n target.parentElement.append(animationDiv);\n } else {\n appImManager.emojiAnimationContainer.append(animationDiv);\n }\n\n return {animationDiv, stickerPromise};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport rootScope from '../../lib/rootScope';\nimport wrapSticker from './sticker'\nimport {Modify} from '../../types';\n\nexport default async function wrapStickerEmoji(options: Modify<Parameters<typeof wrapSticker>[0], {\n div: HTMLElement,\n doc?: never,\n loop?: never\n}>) {\n const {\n emoji,\n div,\n managers = rootScope.managers\n } = options;\n const doc = await managers.appStickersManager.getAnimatedEmojiSticker(emoji);\n if(!doc) {\n div.classList.add('media-sticker-wrapper');\n throw new Error('no sticker');\n }\n\n return wrapSticker({\n doc,\n play: true,\n loop: false,\n ...options\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport createVideo from '../../helpers/dom/createVideo';\nimport renderImageFromUrl from '../../helpers/dom/renderImageFromUrl';\nimport {Document, StickerSet} from '../../layer';\nimport appDownloadManager from '../../lib/appManagers/appDownloadManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport lottieLoader from '../../lib/rlottie/lottieLoader';\nimport rootScope from '../../lib/rootScope';\nimport animationIntersector, {AnimationItemGroup} from '../animationIntersector';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport wrapSticker from './sticker';\nimport {Middleware} from '../../helpers/middleware';\n\nexport default async function wrapStickerSetThumb({set, lazyLoadQueue, container, group, autoplay, width, height, managers = rootScope.managers, middleware}: {\n set: StickerSet.stickerSet,\n lazyLoadQueue: LazyLoadQueue,\n container: HTMLElement,\n group: AnimationItemGroup,\n autoplay: boolean,\n width: number,\n height: number,\n managers?: AppManagers\n middleware?: Middleware\n}) {\n if(set.thumbs?.length) {\n container.classList.add('media-sticker-wrapper');\n lazyLoadQueue.push({\n div: container,\n load: async() => {\n const downloadOptions = await managers.appStickersManager.getStickerSetThumbDownloadOptions(set);\n const promise = appDownloadManager.download(downloadOptions);\n\n if(set.pFlags.animated && !set.pFlags.videos) {\n return promise\n .then((blob) => {\n lottieLoader.loadAnimationWorker({\n container,\n loop: true,\n autoplay,\n animationData: blob,\n width,\n height,\n needUpscale: true,\n name: 'setThumb' + set.id,\n group,\n middleware\n });\n });\n } else {\n let media: HTMLElement;\n if(set.pFlags.videos) {\n media = createVideo();\n (media as HTMLVideoElement).autoplay = true;\n (media as HTMLVideoElement).muted = true;\n (media as HTMLVideoElement).loop = true;\n } else {\n media = new Image();\n }\n\n media.classList.add('media-sticker');\n\n return promise.then((blob) => {\n renderImageFromUrl(media, URL.createObjectURL(blob), () => {\n container.append(media);\n\n if(set.pFlags.videos) {\n animationIntersector.addAnimation({\n animation: media as HTMLVideoElement,\n group\n });\n }\n });\n });\n }\n }\n });\n\n return;\n }\n\n let getDocPromise: Promise<Document>;\n\n if(set.thumb_document_id) {\n getDocPromise = managers.appEmojiManager.getCustomEmojiDocument(set.thumb_document_id);\n } else {\n getDocPromise = managers.appStickersManager.getStickerSet(set).then((stickerSet) => stickerSet.documents[0]);\n }\n\n const doc = await getDocPromise;\n if(doc._ !== 'documentEmpty') { // as thumb will be used first sticker\n wrapSticker({\n doc,\n div: container,\n group: group,\n lazyLoadQueue,\n managers,\n width,\n height,\n middleware\n }); // kostil\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport Row from '../row';\nimport wrapSticker from './sticker';\n\nexport default function wrapStickerToRow({doc, row, size, managers}: {\n doc: MyDocument,\n row: Row,\n size?: 'small' | 'large',\n managers?: AppManagers\n}) {\n const previousMedia = row.media;\n const media = row.createMedia('small');\n\n if(previousMedia) {\n media.classList.add('hide');\n }\n\n const loadPromises: Promise<any>[] = previousMedia ? [] : undefined;\n\n const _size = size === 'small' ? 32 : 48;\n const result = wrapSticker({\n div: media,\n doc: doc,\n width: _size,\n height: _size,\n loadPromises,\n managers\n }).then(({render}) => render);\n\n loadPromises && Promise.all(loadPromises).then(() => {\n media.classList.remove('hide');\n previousMedia.remove();\n });\n\n return result;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport getServerMessageId from '../../lib/appManagers/utils/messageId/getServerMessageId';\nimport {i18n} from '../../lib/langPack';\nimport wrapTelegramUrlToAnchor from '../../lib/richTextProcessor/wrapTelegramUrlToAnchor';\nimport rootScope from '../../lib/rootScope';\nimport wrapPeerTitle from './peerTitle';\n\nexport default async function wrapTopicNameButton(\n options: {\n lastMsgId?: number\n } & Pick<Parameters<typeof wrapPeerTitle>[0], 'peerId' | 'threadId' | 'wrapOptions' | 'withIcons'>\n) {\n const {peerId, threadId, lastMsgId} = options;\n\n const loadPromise: Promise<any> = Promise.resolve();\n const a = wrapTelegramUrlToAnchor('t.me/c/' + peerId.toChatId() + (threadId ? '/' + getServerMessageId(threadId) : '') + (lastMsgId ? '/' + getServerMessageId(lastMsgId) : ''));\n a.classList.add('topic-name', 'topic-name-button');\n // if(threadId) {\n // const topic = await rootScope.managers.dialogsStorage.getForumTopic(peerId, threadId);\n // if(!topic) {\n // a.append(i18n('Loading'));\n // loadPromise = rootScope.managers.dialogsStorage.getForumTopicById(peerId, threadId)\n // }\n // } else {\n a.append(await wrapPeerTitle(options));\n // }\n\n return {\n cached: true,\n element: a,\n loadPromise\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {IS_SAFARI} from '../../environment/userAgent';\nimport {animateSingle} from '../../helpers/animation';\nimport {ChatAutoDownloadSettings} from '../../helpers/autoDownload';\nimport deferredPromise from '../../helpers/cancellablePromise';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport createVideo from '../../helpers/dom/createVideo';\nimport isInDOM from '../../helpers/dom/isInDOM';\nimport renderImageFromUrl from '../../helpers/dom/renderImageFromUrl';\nimport getStrippedThumbIfNeeded from '../../helpers/getStrippedThumbIfNeeded';\nimport liteMode from '../../helpers/liteMode';\nimport makeError from '../../helpers/makeError';\nimport mediaSizes, {ScreenSize} from '../../helpers/mediaSizes';\nimport {Middleware} from '../../helpers/middleware';\nimport noop from '../../helpers/noop';\nimport onMediaLoad from '../../helpers/onMediaLoad';\nimport {fastRaf} from '../../helpers/schedulers';\nimport throttle from '../../helpers/schedulers/throttle';\nimport sequentialDom from '../../helpers/sequentialDom';\nimport toHHMMSS from '../../helpers/string/toHHMMSS';\nimport {Message, PhotoSize, VideoSize} from '../../layer';\nimport {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport appDownloadManager from '../../lib/appManagers/appDownloadManager';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport {NULL_PEER_ID} from '../../lib/mtproto/mtproto_config';\nimport rootScope from '../../lib/rootScope';\nimport {ThumbCache} from '../../lib/storages/thumbs';\nimport animationIntersector, {AnimationItemGroup} from '../animationIntersector';\nimport appMediaPlaybackController, {MediaSearchContext} from '../appMediaPlaybackController';\nimport AudioElement, {findMediaTargets} from '../audio';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport ProgressivePreloader from '../preloader';\nimport wrapPhoto from './photo';\n\nconst MAX_VIDEO_AUTOPLAY_SIZE = 50 * 1024 * 1024; // 50 MB\n\nlet roundVideoCircumference = 0;\nmediaSizes.addEventListener('changeScreen', (from, to) => {\n if(to === ScreenSize.mobile || from === ScreenSize.mobile) {\n const elements = Array.from(document.querySelectorAll('.media-round .progress-ring')) as SVGSVGElement[];\n const width = mediaSizes.active.round.width;\n const halfSize = width / 2;\n const radius = halfSize - 7;\n roundVideoCircumference = 2 * Math.PI * radius;\n elements.forEach((element) => {\n element.setAttributeNS(null, 'width', '' + width);\n element.setAttributeNS(null, 'height', '' + width);\n\n const circle = element.firstElementChild as SVGCircleElement;\n circle.setAttributeNS(null, 'cx', '' + halfSize);\n circle.setAttributeNS(null, 'cy', '' + halfSize);\n circle.setAttributeNS(null, 'r', '' + radius);\n\n circle.style.strokeDasharray = roundVideoCircumference + ' ' + roundVideoCircumference;\n circle.style.strokeDashoffset = '' + roundVideoCircumference;\n });\n }\n});\n\nexport default async function wrapVideo({doc, container, message, boxWidth, boxHeight, withTail, isOut, middleware, lazyLoadQueue, noInfo, group, onlyPreview, noPreview, withoutPreloader, loadPromises, noPlayButton, photoSize, videoSize, searchContext, autoDownload, managers = rootScope.managers, noAutoplayAttribute}: {\n doc: MyDocument,\n container?: HTMLElement,\n message?: Message.message,\n boxWidth?: number,\n boxHeight?: number,\n withTail?: boolean,\n isOut?: boolean,\n middleware?: Middleware,\n lazyLoadQueue?: LazyLoadQueue,\n noInfo?: boolean,\n noPlayButton?: boolean,\n group?: AnimationItemGroup,\n onlyPreview?: boolean,\n noPreview?: boolean,\n withoutPreloader?: boolean,\n loadPromises?: Promise<any>[],\n autoDownload?: ChatAutoDownloadSettings,\n photoSize?: PhotoSize,\n videoSize?: Extract<VideoSize, VideoSize.videoSize>,\n searchContext?: MediaSearchContext,\n managers?: AppManagers,\n noAutoplayAttribute?: boolean\n}) {\n const autoDownloadSize = autoDownload?.video;\n let noAutoDownload = autoDownloadSize === 0;\n const isAlbumItem = !(boxWidth && boxHeight);\n const canAutoplay = /* doc.sticker || */(\n (\n doc.type !== 'video' || (\n doc.size <= MAX_VIDEO_AUTOPLAY_SIZE &&\n !isAlbumItem\n )\n ) && (doc.type === 'gif' ? liteMode.isAvailable('gif') : liteMode.isAvailable('video'))\n );\n let spanTime: HTMLElement, spanPlay: HTMLElement;\n\n if(!noInfo) {\n spanTime = document.createElement('span');\n spanTime.classList.add('video-time');\n container.append(spanTime);\n\n let needPlayButton = false;\n if(doc.type !== 'gif') {\n spanTime.innerText = toHHMMSS(doc.duration, false);\n\n if(!noPlayButton && doc.type !== 'round') {\n if(canAutoplay && !noAutoDownload) {\n spanTime.classList.add('tgico', 'can-autoplay');\n } else {\n needPlayButton = true;\n }\n }\n } else {\n spanTime.innerText = 'GIF';\n\n if(!canAutoplay && !noPlayButton) {\n needPlayButton = true;\n noAutoDownload = undefined;\n }\n }\n\n if(needPlayButton) {\n spanPlay = document.createElement('span');\n spanPlay.classList.add('video-play', 'tgico-largeplay', 'btn-circle', 'position-center');\n container.append(spanPlay);\n }\n }\n\n const res: {\n thumb?: typeof photoRes,\n loadPromise: Promise<any>\n } = {} as any;\n\n if(doc.mime_type === 'image/gif') {\n const photoRes = await wrapPhoto({\n photo: doc,\n message,\n container,\n boxWidth,\n boxHeight,\n withTail,\n isOut,\n lazyLoadQueue,\n middleware,\n withoutPreloader,\n loadPromises,\n autoDownloadSize,\n size: photoSize,\n managers\n });\n\n res.thumb = photoRes;\n res.loadPromise = photoRes.loadPromises.full;\n return res;\n }\n\n /* const video = doc.type === 'round' ? appMediaPlaybackController.addMedia(doc, message.mid) as HTMLVideoElement : document.createElement('video');\n if(video.parentElement) {\n video.remove();\n } */\n\n let preloader: ProgressivePreloader; // it must be here, otherwise will get error before initialization in round onPlay\n\n const video = createVideo();\n video.classList.add('media-video');\n video.muted = true;\n if(doc.type === 'round') {\n const divRound = document.createElement('div');\n divRound.classList.add('media-round', 'z-depth-1');\n divRound.dataset.mid = '' + message.mid;\n divRound.dataset.peerId = '' + message.peerId;\n (divRound as any).message = message;\n\n const size = mediaSizes.active.round;\n const halfSize = size.width / 2;\n const strokeWidth = 3.5;\n const radius = halfSize - (strokeWidth * 2);\n divRound.innerHTML = `<svg class=\"progress-ring\" width=\"${size.width}\" height=\"${size.width}\" style=\"transform: rotate(-90deg);\">\n <circle class=\"progress-ring__circle\" stroke=\"white\" stroke-opacity=\"0.3\" stroke-width=\"${strokeWidth}\" cx=\"${halfSize}\" cy=\"${halfSize}\" r=\"${radius}\" fill=\"transparent\"/>\n </svg>`;\n\n const circle = divRound.firstElementChild.firstElementChild as SVGCircleElement;\n if(!roundVideoCircumference) {\n roundVideoCircumference = 2 * Math.PI * radius;\n }\n circle.style.strokeDasharray = roundVideoCircumference + ' ' + roundVideoCircumference;\n circle.style.strokeDashoffset = '' + roundVideoCircumference;\n\n spanTime.classList.add('tgico');\n\n const isUnread = message.pFlags.media_unread;\n if(isUnread) {\n divRound.classList.add('is-unread');\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = canvas.height = doc.w/* * window.devicePixelRatio */;\n\n divRound.prepend(canvas, spanTime);\n divRound.append(video);\n container.append(divRound);\n\n const ctx = canvas.getContext('2d');\n /* ctx.beginPath();\n ctx.arc(canvas.width / 2, canvas.height / 2, canvas.width / 2, 0, Math.PI * 2);\n ctx.clip(); */\n\n const onLoad = () => {\n const message: Message.message = (divRound as any).message;\n const globalVideo = appMediaPlaybackController.addMedia(message, !noAutoDownload) as HTMLVideoElement;\n const clear = () => {\n (appImManager.chat.setPeerPromise || Promise.resolve()).finally(() => {\n if(isInDOM(globalVideo)) {\n return;\n }\n\n globalVideo.removeEventListener('play', onPlay);\n globalVideo.removeEventListener('timeupdate', throttledTimeUpdate);\n globalVideo.removeEventListener('pause', onPaused);\n globalVideo.removeEventListener('ended', onEnded);\n });\n };\n\n const onFrame = () => {\n ctx.drawImage(globalVideo, 0, 0);\n\n const offset = roundVideoCircumference - globalVideo.currentTime / globalVideo.duration * roundVideoCircumference;\n circle.style.strokeDashoffset = '' + offset;\n\n return !globalVideo.paused;\n };\n\n const onTimeUpdate = () => {\n if(!globalVideo.duration) {\n return;\n }\n\n if(!isInDOM(globalVideo)) {\n clear();\n return;\n }\n\n if(globalVideo.paused) {\n onFrame();\n }\n\n spanTime.innerText = toHHMMSS(globalVideo.duration - globalVideo.currentTime, false);\n };\n\n const throttledTimeUpdate = throttle(() => {\n fastRaf(onTimeUpdate);\n }, 1000, false);\n\n const onPlay = () => {\n video.classList.add('hide');\n divRound.classList.remove('is-paused');\n animateSingle(onFrame, canvas);\n\n if(preloader && preloader.preloader && preloader.preloader.classList.contains('manual')) {\n preloader.onClick();\n }\n };\n\n const onPaused = () => {\n if(!isInDOM(globalVideo)) {\n clear();\n return;\n }\n\n divRound.classList.add('is-paused');\n };\n\n const onEnded = () => {\n video.classList.remove('hide');\n divRound.classList.add('is-paused');\n\n video.currentTime = 0;\n spanTime.innerText = toHHMMSS(globalVideo.duration, false);\n\n if(globalVideo.currentTime) {\n globalVideo.currentTime = 0;\n }\n };\n\n globalVideo.addEventListener('play', onPlay);\n globalVideo.addEventListener('timeupdate', throttledTimeUpdate);\n globalVideo.addEventListener('pause', onPaused);\n globalVideo.addEventListener('ended', onEnded);\n\n attachClickEvent(canvas, (e) => {\n cancelEvent(e);\n\n // ! костыль\n if(preloader && !preloader.detached) {\n preloader.onClick();\n }\n\n // ! can't use it here. on Safari iOS video won't start.\n /* if(globalVideo.readyState < 2) {\n return;\n } */\n\n if(globalVideo.paused) {\n const hadSearchContext = !!searchContext;\n if(appMediaPlaybackController.setSearchContext(searchContext || {\n peerId: NULL_PEER_ID,\n inputFilter: {_: 'inputMessagesFilterEmpty'},\n useSearch: false\n })) {\n const [prev, next] = !hadSearchContext ? [] : findMediaTargets(divRound, message.mid/* , searchContext.useSearch */);\n appMediaPlaybackController.setTargets({peerId: message.peerId, mid: message.mid}, prev, next);\n }\n\n globalVideo.play();\n } else {\n globalVideo.pause();\n }\n });\n\n if(globalVideo.paused) {\n if(globalVideo.duration && globalVideo.currentTime !== globalVideo.duration && globalVideo.currentTime > 0) {\n onFrame();\n onTimeUpdate();\n video.classList.add('hide');\n } else {\n onPaused();\n }\n } else {\n onPlay();\n }\n };\n\n if(message.pFlags.is_outgoing) {\n // ! WARNING ! just to type-check\n (divRound as any as AudioElement).onLoad = onLoad;\n divRound.dataset.isOutgoing = '1';\n } else {\n onLoad();\n }\n } else if(!noAutoplayAttribute) {\n video.autoplay = true; // для safari\n }\n\n let photoRes: Awaited<ReturnType<typeof wrapPhoto>>;\n if(message) {\n photoRes = await wrapPhoto({\n photo: doc,\n message,\n container,\n boxWidth,\n boxHeight,\n withTail,\n isOut,\n lazyLoadQueue,\n middleware,\n withoutPreloader: true,\n loadPromises,\n autoDownloadSize: autoDownload?.photo,\n size: photoSize,\n managers\n });\n\n res.thumb = photoRes;\n\n if((!canAutoplay && doc.type !== 'gif') || onlyPreview) {\n res.loadPromise = photoRes.loadPromises.full;\n return res;\n }\n\n if(withTail) {\n const foreignObject = (photoRes.images.thumb || photoRes.images.full).parentElement;\n video.width = +foreignObject.getAttributeNS(null, 'width');\n video.height = +foreignObject.getAttributeNS(null, 'height');\n foreignObject.append(video);\n }\n } else if(!noPreview) { // * gifs masonry\n const gotThumb = getStrippedThumbIfNeeded(doc, {} as ThumbCache, true);\n if(gotThumb) {\n const thumbImage = gotThumb.image;\n thumbImage.classList.add('media-poster');\n container.append(thumbImage);\n res.thumb = {\n loadPromises: {\n thumb: gotThumb.loadPromise,\n full: Promise.resolve()\n },\n images: {\n thumb: thumbImage,\n full: null\n },\n preloader: null,\n aspecter: null\n };\n\n loadPromises?.push(gotThumb.loadPromise);\n res.loadPromise = gotThumb.loadPromise;\n }\n }\n\n if(onlyPreview) {\n return res;\n }\n\n if(!video.parentElement && container) {\n (photoRes?.aspecter || container).append(video);\n }\n\n let cacheContext: ThumbCache;\n const getCacheContext = async() => {\n return cacheContext = await managers.thumbsStorage.getCacheContext(doc, videoSize?.type);\n };\n\n await getCacheContext();\n\n const uploadFileName = message?.uploadingFileName;\n if(uploadFileName) { // means upload\n preloader = new ProgressivePreloader({\n attachMethod: 'prepend',\n isUpload: true\n });\n preloader.attachPromise(appDownloadManager.getUpload(uploadFileName));\n preloader.attach(container, false);\n noAutoDownload = undefined;\n } else if(!cacheContext.downloaded && !doc.supportsStreaming && !withoutPreloader) {\n preloader = new ProgressivePreloader({\n attachMethod: 'prepend'\n });\n } else if(doc.supportsStreaming) {\n preloader = new ProgressivePreloader({\n cancelable: false,\n attachMethod: 'prepend'\n });\n }\n\n const renderDeferred = deferredPromise<void>();\n video.addEventListener('error', (e) => {\n if(video.error.code !== 4) {\n console.error('Error ' + video.error.code + '; details: ' + video.error.message);\n }\n\n if(preloader && !uploadFileName) {\n preloader.detach();\n }\n\n if(!renderDeferred.isFulfilled) {\n renderDeferred.resolve();\n }\n }, {once: true});\n\n if(doc.type === 'video') {\n const onTimeUpdate = () => {\n if(!video.duration) {\n return;\n }\n\n spanTime.innerText = toHHMMSS(video.duration - video.currentTime, false);\n };\n\n const throttledTimeUpdate = throttle(() => {\n fastRaf(onTimeUpdate);\n }, 1e3, false);\n\n video.addEventListener('timeupdate', throttledTimeUpdate);\n\n if(spanPlay) {\n video.addEventListener('timeupdate', () => {\n sequentialDom.mutateElement(spanPlay, () => {\n spanPlay.remove();\n });\n }, {once: true});\n }\n }\n\n video.muted = true;\n video.loop = true;\n // video.play();\n if(!noAutoplayAttribute) {\n video.autoplay = true;\n }\n\n let loadPhotoThumbFunc = noAutoDownload && photoRes?.preloader?.loadFunc;\n const load = async() => {\n if(preloader && noAutoDownload && !withoutPreloader) {\n preloader.construct();\n preloader.setManual();\n }\n\n await getCacheContext();\n let loadPromise: Promise<any> = Promise.resolve();\n if((preloader && !uploadFileName) || withoutPreloader) {\n if(!cacheContext.downloaded && !doc.supportsStreaming) {\n const promise = loadPromise = appDownloadManager.downloadMediaURL({\n media: doc,\n queueId: lazyLoadQueue?.queueId,\n onlyCache: noAutoDownload,\n thumb: videoSize\n });\n\n if(preloader) {\n preloader.attach(container, false, promise);\n }\n } else if(doc.supportsStreaming) {\n if(noAutoDownload) {\n loadPromise = Promise.reject(makeError('NO_AUTO_DOWNLOAD'));\n } else if(!cacheContext.downloaded && preloader) { // * check for uploading video\n preloader.attach(container, false, null);\n video.addEventListener(IS_SAFARI ? 'timeupdate' : 'canplay', () => {\n preloader.detach();\n }, {once: true});\n }\n }\n }\n\n if(!noAutoDownload && loadPhotoThumbFunc) {\n loadPhotoThumbFunc();\n loadPhotoThumbFunc = null;\n }\n\n noAutoDownload = undefined;\n\n loadPromise.then(async() => {\n if(middleware && !middleware()) {\n renderDeferred.resolve();\n return;\n }\n\n if(doc.type === 'round') {\n appMediaPlaybackController.resolveWaitingForLoadMedia(message.peerId, message.mid, message.pFlags.is_scheduled);\n }\n\n await getCacheContext();\n\n onMediaLoad(video).then(() => {\n if(group) {\n animationIntersector.addAnimation({\n animation: video,\n group\n });\n }\n\n if(preloader && !uploadFileName) {\n preloader.detach();\n }\n\n renderDeferred.resolve();\n }, (err) => {\n console.error('video load error', err);\n if(spanTime) {\n spanTime.classList.add('is-error');\n }\n renderDeferred.reject(err);\n });\n\n renderImageFromUrl(video, cacheContext.url);\n }, noop);\n\n return {download: loadPromise, render: Promise.all([loadPromise, renderDeferred])};\n };\n\n if(preloader && !uploadFileName) {\n preloader.setDownloadFunction(load);\n }\n\n (container as any).preloader = preloader;\n\n /* if(doc.size >= 20e6 && !doc.downloaded) {\n let downloadDiv = document.createElement('div');\n downloadDiv.classList.add('download');\n\n let span = document.createElement('span');\n span.classList.add('btn-circle', 'tgico-download');\n downloadDiv.append(span);\n\n downloadDiv.addEventListener('click', () => {\n downloadDiv.remove();\n loadVideo();\n });\n\n container.prepend(downloadDiv);\n\n return;\n } */\n\n if(doc.type === 'gif' && !canAutoplay) {\n attachClickEvent(container, (e) => {\n cancelEvent(e);\n spanPlay.remove();\n load();\n }, {capture: true, once: true});\n } else {\n res.loadPromise = !lazyLoadQueue ?\n (await load()).render :\n (lazyLoadQueue.push({div: container, load: () => load().then(({render}) => render)}), Promise.resolve());\n }\n\n if(res.thumb) {\n await res.thumb.loadPromises.thumb;\n }\n\n return res;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport limitSymbols from '../../helpers/string/limitSymbols';\nimport {WebPage} from '../../layer';\nimport wrapRichText from '../../lib/richTextProcessor/wrapRichText';\n\nexport default function wrapWebPageDescription(webPage: WebPage.webPage) {\n const shortDescriptionText = limitSymbols(webPage.description || '', 150, 180);\n // const siteName = webPage.site_name;\n // let contextHashtag = '';\n // if(siteName === 'GitHub') {\n // const matches = apiWebPage.url.match(/(https?:\\/\\/github\\.com\\/[^\\/]+\\/[^\\/]+)/);\n // if(matches) {\n // contextHashtag = matches[0] + '/issues/{1}';\n // }\n // }\n return wrapRichText(shortDescriptionText/* , {\n contextSite: siteName || 'external',\n contextHashtag: contextHashtag\n } */);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport limitSymbols from '../../helpers/string/limitSymbols';\nimport {WebPage} from '../../layer';\nimport wrapRichText from '../../lib/richTextProcessor/wrapRichText';\n\nexport default function wrapWebPageTitle(webPage: WebPage.webPage) {\n let shortTitle = webPage.title || webPage.author || webPage.site_name || '';\n shortTitle = limitSymbols(shortTitle, 80, 100);\n return wrapRichText(shortTitle, {noLinks: true, noLinebreaks: true});\n}\n","// Taken from https://core.telegram.org/bots/payments/currencies.json\nexport type Currency = {\n code: string,\n title: string,\n symbol: string,\n native: string,\n thousands_sep: string,\n decimal_sep: string,\n symbol_left: boolean,\n space_between: boolean,\n exp: number,\n min_amount: string | number,\n max_amount: string | number\n};\n\n// eslint-disable-next-line quotes, comma-spacing\nconst Currencies: {[currency: string]: Currency} = {\"AED\":{\"code\":\"AED\",\"title\":\"United Arab Emirates Dirham\",\"symbol\":\"AED\",\"native\":\"د.إ.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"367\",\"max_amount\":\"3673030\"},\"AFN\":{\"code\":\"AFN\",\"title\":\"Afghan Afghani\",\"symbol\":\"AFN\",\"native\":\"؋\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"8729\",\"max_amount\":\"87299487\"},\"ALL\":{\"code\":\"ALL\",\"title\":\"Albanian Lek\",\"symbol\":\"ALL\",\"native\":\"Lek\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":false,\"exp\":2,\"min_amount\":\"11842\",\"max_amount\":\"118421187\"},\"AMD\":{\"code\":\"AMD\",\"title\":\"Armenian Dram\",\"symbol\":\"AMD\",\"native\":\"դր.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"40943\",\"max_amount\":\"409436718\"},\"ARS\":{\"code\":\"ARS\",\"title\":\"Argentine Peso\",\"symbol\":\"ARS\",\"native\":\"$\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"14705\",\"max_amount\":\"147059002\"},\"AUD\":{\"code\":\"AUD\",\"title\":\"Australian Dollar\",\"symbol\":\"AU$\",\"native\":\"$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"153\",\"max_amount\":\"1536825\"},\"AZN\":{\"code\":\"AZN\",\"title\":\"Azerbaijani Manat\",\"symbol\":\"AZN\",\"native\":\"ман.\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"169\",\"max_amount\":\"1699858\"},\"BAM\":{\"code\":\"BAM\",\"title\":\"Bosnia & Herzegovina Convertible Mark\",\"symbol\":\"BAM\",\"native\":\"KM\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"199\",\"max_amount\":\"1990677\"},\"BDT\":{\"code\":\"BDT\",\"title\":\"Bangladeshi Taka\",\"symbol\":\"BDT\",\"native\":\"৳\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"10009\",\"max_amount\":\"100094046\"},\"BGN\":{\"code\":\"BGN\",\"title\":\"Bulgarian Lev\",\"symbol\":\"BGN\",\"native\":\"лв.\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"199\",\"max_amount\":\"1993315\"},\"BND\":{\"code\":\"BND\",\"title\":\"Brunei Dollar\",\"symbol\":\"BND\",\"native\":\"$\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"142\",\"max_amount\":\"1421883\"},\"BOB\":{\"code\":\"BOB\",\"title\":\"Bolivian Boliviano\",\"symbol\":\"BOB\",\"native\":\"Bs\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"683\",\"max_amount\":\"6832607\"},\"BRL\":{\"code\":\"BRL\",\"title\":\"Brazilian Real\",\"symbol\":\"R$\",\"native\":\"R$\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"539\",\"max_amount\":\"5397799\"},\"BYN\":{\"code\":\"BYN\",\"title\":\"Belarusian ruble\",\"symbol\":\"BYN\",\"native\":\"BYN\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"249\",\"max_amount\":\"2495801\"},\"CAD\":{\"code\":\"CAD\",\"title\":\"Canadian Dollar\",\"symbol\":\"CA$\",\"native\":\"$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"136\",\"max_amount\":\"1366860\"},\"CHF\":{\"code\":\"CHF\",\"title\":\"Swiss Franc\",\"symbol\":\"CHF\",\"native\":\"CHF\",\"thousands_sep\":\"'\",\"decimal_sep\":\".\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"97\",\"max_amount\":\"976705\"},\"CLP\":{\"code\":\"CLP\",\"title\":\"Chilean Peso\",\"symbol\":\"CLP\",\"native\":\"$\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":true,\"exp\":0,\"min_amount\":\"963\",\"max_amount\":\"9637495\"},\"CNY\":{\"code\":\"CNY\",\"title\":\"Chinese Renminbi Yuan\",\"symbol\":\"CN¥\",\"native\":\"CN¥\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"709\",\"max_amount\":\"7094102\"},\"COP\":{\"code\":\"COP\",\"title\":\"Colombian Peso\",\"symbol\":\"COP\",\"native\":\"$\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"452870\",\"max_amount\":\"4528700000\"},\"CRC\":{\"code\":\"CRC\",\"title\":\"Costa Rican Colón\",\"symbol\":\"CRC\",\"native\":\"₡\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"62506\",\"max_amount\":\"625061070\"},\"CZK\":{\"code\":\"CZK\",\"title\":\"Czech Koruna\",\"symbol\":\"CZK\",\"native\":\"Kč\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"2497\",\"max_amount\":\"24975029\"},\"DKK\":{\"code\":\"DKK\",\"title\":\"Danish Krone\",\"symbol\":\"DKK\",\"native\":\"kr\",\"thousands_sep\":\"\",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"755\",\"max_amount\":\"7555990\"},\"DOP\":{\"code\":\"DOP\",\"title\":\"Dominican Peso\",\"symbol\":\"DOP\",\"native\":\"$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"5275\",\"max_amount\":\"52757308\"},\"DZD\":{\"code\":\"DZD\",\"title\":\"Algerian Dinar\",\"symbol\":\"DZD\",\"native\":\"د.ج.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"14035\",\"max_amount\":\"140353307\"},\"EGP\":{\"code\":\"EGP\",\"title\":\"Egyptian Pound\",\"symbol\":\"EGP\",\"native\":\"ج.م.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"1953\",\"max_amount\":\"19537405\"},\"ETB\":{\"code\":\"ETB\",\"title\":\"Ethiopian Birr\",\"symbol\":\"ETB\",\"native\":\"ብር\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"5224\",\"max_amount\":\"52247069\"},\"EUR\":{\"code\":\"EUR\",\"title\":\"Euro\",\"symbol\":\"€\",\"native\":\"€\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"101\",\"max_amount\":\"1016045\"},\"GBP\":{\"code\":\"GBP\",\"title\":\"British Pound\",\"symbol\":\"£\",\"native\":\"£\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"89\",\"max_amount\":\"894445\"},\"GEL\":{\"code\":\"GEL\",\"title\":\"Georgian Lari\",\"symbol\":\"GEL\",\"native\":\"GEL\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"283\",\"max_amount\":\"2830234\"},\"GTQ\":{\"code\":\"GTQ\",\"title\":\"Guatemalan Quetzal\",\"symbol\":\"GTQ\",\"native\":\"Q\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"778\",\"max_amount\":\"7781323\"},\"HKD\":{\"code\":\"HKD\",\"title\":\"Hong Kong Dollar\",\"symbol\":\"HK$\",\"native\":\"$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"784\",\"max_amount\":\"7849750\"},\"HNL\":{\"code\":\"HNL\",\"title\":\"Honduran Lempira\",\"symbol\":\"HNL\",\"native\":\"L\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"2441\",\"max_amount\":\"24413729\"},\"HRK\":{\"code\":\"HRK\",\"title\":\"Croatian Kuna\",\"symbol\":\"HRK\",\"native\":\"kn\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"764\",\"max_amount\":\"7648805\"},\"HUF\":{\"code\":\"HUF\",\"title\":\"Hungarian Forint\",\"symbol\":\"HUF\",\"native\":\"Ft\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"42685\",\"max_amount\":\"426850229\"},\"IDR\":{\"code\":\"IDR\",\"title\":\"Indonesian Rupiah\",\"symbol\":\"IDR\",\"native\":\"Rp\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"1523370\",\"max_amount\":\"15233700000\"},\"ILS\":{\"code\":\"ILS\",\"title\":\"Israeli New Sheqel\",\"symbol\":\"₪\",\"native\":\"₪\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"354\",\"max_amount\":\"3543350\"},\"INR\":{\"code\":\"INR\",\"title\":\"Indian Rupee\",\"symbol\":\"₹\",\"native\":\"₹\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"8155\",\"max_amount\":\"81555550\"},\"ISK\":{\"code\":\"ISK\",\"title\":\"Icelandic Króna\",\"symbol\":\"ISK\",\"native\":\"kr\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":0,\"min_amount\":\"142\",\"max_amount\":\"1425603\"},\"JMD\":{\"code\":\"JMD\",\"title\":\"Jamaican Dollar\",\"symbol\":\"JMD\",\"native\":\"$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"15013\",\"max_amount\":\"150131044\"},\"JPY\":{\"code\":\"JPY\",\"title\":\"Japanese Yen\",\"symbol\":\"¥\",\"native\":\"¥\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":0,\"min_amount\":\"144\",\"max_amount\":\"1443065\"},\"KES\":{\"code\":\"KES\",\"title\":\"Kenyan Shilling\",\"symbol\":\"KES\",\"native\":\"Ksh\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"12075\",\"max_amount\":\"120750271\"},\"KGS\":{\"code\":\"KGS\",\"title\":\"Kyrgyzstani Som\",\"symbol\":\"KGS\",\"native\":\"KGS\",\"thousands_sep\":\" \",\"decimal_sep\":\"-\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"8018\",\"max_amount\":\"80182898\"},\"KRW\":{\"code\":\"KRW\",\"title\":\"South Korean Won\",\"symbol\":\"₩\",\"native\":\"₩\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":0,\"min_amount\":\"1431\",\"max_amount\":\"14315201\"},\"KZT\":{\"code\":\"KZT\",\"title\":\"Kazakhstani Tenge\",\"symbol\":\"KZT\",\"native\":\"₸\",\"thousands_sep\":\" \",\"decimal_sep\":\"-\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"47186\",\"max_amount\":\"471867112\"},\"LBP\":{\"code\":\"LBP\",\"title\":\"Lebanese Pound\",\"symbol\":\"LBP\",\"native\":\"ل.ل.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"150999\",\"max_amount\":\"1509998778\"},\"LKR\":{\"code\":\"LKR\",\"title\":\"Sri Lankan Rupee\",\"symbol\":\"LKR\",\"native\":\"රු.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"35546\",\"max_amount\":\"355469651\"},\"MAD\":{\"code\":\"MAD\",\"title\":\"Moroccan Dirham\",\"symbol\":\"MAD\",\"native\":\"د.م.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"1093\",\"max_amount\":\"10938136\"},\"MDL\":{\"code\":\"MDL\",\"title\":\"Moldovan Leu\",\"symbol\":\"MDL\",\"native\":\"MDL\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"1926\",\"max_amount\":\"19264439\"},\"MNT\":{\"code\":\"MNT\",\"title\":\"Mongolian Tögrög\",\"symbol\":\"MNT\",\"native\":\"MNT\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"322444\",\"max_amount\":\"3224442056\"},\"MUR\":{\"code\":\"MUR\",\"title\":\"Mauritian Rupee\",\"symbol\":\"MUR\",\"native\":\"MUR\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"4453\",\"max_amount\":\"44535174\"},\"MVR\":{\"code\":\"MVR\",\"title\":\"Maldivian Rufiyaa\",\"symbol\":\"MVR\",\"native\":\"MVR\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"1546\",\"max_amount\":\"15460397\"},\"MXN\":{\"code\":\"MXN\",\"title\":\"Mexican Peso\",\"symbol\":\"MX$\",\"native\":\"$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"2012\",\"max_amount\":\"20122860\"},\"MYR\":{\"code\":\"MYR\",\"title\":\"Malaysian Ringgit\",\"symbol\":\"MYR\",\"native\":\"RM\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"463\",\"max_amount\":\"4632502\"},\"MZN\":{\"code\":\"MZN\",\"title\":\"Mozambican Metical\",\"symbol\":\"MZN\",\"native\":\"MTn\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"6382\",\"max_amount\":\"63829729\"},\"NGN\":{\"code\":\"NGN\",\"title\":\"Nigerian Naira\",\"symbol\":\"NGN\",\"native\":\"₦\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"43203\",\"max_amount\":\"432039828\"},\"NIO\":{\"code\":\"NIO\",\"title\":\"Nicaraguan Córdoba\",\"symbol\":\"NIO\",\"native\":\"C$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"3556\",\"max_amount\":\"35566412\"},\"NOK\":{\"code\":\"NOK\",\"title\":\"Norwegian Krone\",\"symbol\":\"NOK\",\"native\":\"kr\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"1069\",\"max_amount\":\"10690975\"},\"NPR\":{\"code\":\"NPR\",\"title\":\"Nepalese Rupee\",\"symbol\":\"NPR\",\"native\":\"नेरू\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"12954\",\"max_amount\":\"129546657\"},\"NZD\":{\"code\":\"NZD\",\"title\":\"New Zealand Dollar\",\"symbol\":\"NZ$\",\"native\":\"$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"174\",\"max_amount\":\"1746220\"},\"PAB\":{\"code\":\"PAB\",\"title\":\"Panamanian Balboa\",\"symbol\":\"PAB\",\"native\":\"B\\/.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"98\",\"max_amount\":\"988722\"},\"PEN\":{\"code\":\"PEN\",\"title\":\"Peruvian Nuevo Sol\",\"symbol\":\"PEN\",\"native\":\"S\\/.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"390\",\"max_amount\":\"3902208\"},\"PHP\":{\"code\":\"PHP\",\"title\":\"Philippine Peso\",\"symbol\":\"PHP\",\"native\":\"₱\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"5862\",\"max_amount\":\"58627496\"},\"PKR\":{\"code\":\"PKR\",\"title\":\"Pakistani Rupee\",\"symbol\":\"PKR\",\"native\":\"₨\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"22642\",\"max_amount\":\"226426805\"},\"PLN\":{\"code\":\"PLN\",\"title\":\"Polish Złoty\",\"symbol\":\"PLN\",\"native\":\"zł\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"493\",\"max_amount\":\"4932350\"},\"PYG\":{\"code\":\"PYG\",\"title\":\"Paraguayan Guaraní\",\"symbol\":\"PYG\",\"native\":\"₲\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":true,\"exp\":0,\"min_amount\":\"6977\",\"max_amount\":\"69772317\"},\"QAR\":{\"code\":\"QAR\",\"title\":\"Qatari Riyal\",\"symbol\":\"QAR\",\"native\":\"ر.ق.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"364\",\"max_amount\":\"3640989\"},\"RON\":{\"code\":\"RON\",\"title\":\"Romanian Leu\",\"symbol\":\"RON\",\"native\":\"RON\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"502\",\"max_amount\":\"5028645\"},\"RSD\":{\"code\":\"RSD\",\"title\":\"Serbian Dinar\",\"symbol\":\"RSD\",\"native\":\"дин.\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"11918\",\"max_amount\":\"119184990\"},\"RUB\":{\"code\":\"RUB\",\"title\":\"Russian Ruble\",\"symbol\":\"RUB\",\"native\":\"₽\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"7128\",\"max_amount\":\"71281218\"},\"SAR\":{\"code\":\"SAR\",\"title\":\"Saudi Riyal\",\"symbol\":\"SAR\",\"native\":\"ر.س.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"375\",\"max_amount\":\"3756546\"},\"SEK\":{\"code\":\"SEK\",\"title\":\"Swedish Krona\",\"symbol\":\"SEK\",\"native\":\"kr\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"1109\",\"max_amount\":\"11094972\"},\"SGD\":{\"code\":\"SGD\",\"title\":\"Singapore Dollar\",\"symbol\":\"SGD\",\"native\":\"$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"143\",\"max_amount\":\"1430495\"},\"THB\":{\"code\":\"THB\",\"title\":\"Thai Baht\",\"symbol\":\"฿\",\"native\":\"฿\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"3780\",\"max_amount\":\"37800497\"},\"TJS\":{\"code\":\"TJS\",\"title\":\"Tajikistani Somoni\",\"symbol\":\"TJS\",\"native\":\"TJS\",\"thousands_sep\":\" \",\"decimal_sep\":\";\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"975\",\"max_amount\":\"9753854\"},\"TRY\":{\"code\":\"TRY\",\"title\":\"Turkish Lira\",\"symbol\":\"TRY\",\"native\":\"TL\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"1854\",\"max_amount\":\"18543598\"},\"TTD\":{\"code\":\"TTD\",\"title\":\"Trinidad and Tobago Dollar\",\"symbol\":\"TTD\",\"native\":\"$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"672\",\"max_amount\":\"6722681\"},\"TWD\":{\"code\":\"TWD\",\"title\":\"New Taiwan Dollar\",\"symbol\":\"NT$\",\"native\":\"NT$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"3173\",\"max_amount\":\"31738502\"},\"TZS\":{\"code\":\"TZS\",\"title\":\"Tanzanian Shilling\",\"symbol\":\"TZS\",\"native\":\"TSh\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"233199\",\"max_amount\":\"2331999890\"},\"UAH\":{\"code\":\"UAH\",\"title\":\"Ukrainian Hryvnia\",\"symbol\":\"UAH\",\"native\":\"₴\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":false,\"exp\":2,\"min_amount\":\"3633\",\"max_amount\":\"36338830\"},\"UGX\":{\"code\":\"UGX\",\"title\":\"Ugandan Shilling\",\"symbol\":\"UGX\",\"native\":\"USh\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":0,\"min_amount\":\"3816\",\"max_amount\":\"38166726\"},\"USD\":{\"code\":\"USD\",\"title\":\"United States Dollar\",\"symbol\":\"$\",\"native\":\"$\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":false,\"exp\":2,\"min_amount\":\"100\",\"max_amount\":1000000},\"UYU\":{\"code\":\"UYU\",\"title\":\"Uruguayan Peso\",\"symbol\":\"UYU\",\"native\":\"$\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"4080\",\"max_amount\":\"40801205\"},\"UZS\":{\"code\":\"UZS\",\"title\":\"Uzbekistani Som\",\"symbol\":\"UZS\",\"native\":\"UZS\",\"thousands_sep\":\" \",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":2,\"min_amount\":\"1089058\",\"max_amount\":\"10890583014\"},\"VND\":{\"code\":\"VND\",\"title\":\"Vietnamese Đồng\",\"symbol\":\"₫\",\"native\":\"₫\",\"thousands_sep\":\".\",\"decimal_sep\":\",\",\"symbol_left\":false,\"space_between\":true,\"exp\":0,\"min_amount\":\"23862\",\"max_amount\":\"238625000\"},\"YER\":{\"code\":\"YER\",\"title\":\"Yemeni Rial\",\"symbol\":\"YER\",\"native\":\"ر.ي.\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"25030\",\"max_amount\":\"250300677\"},\"ZAR\":{\"code\":\"ZAR\",\"title\":\"South African Rand\",\"symbol\":\"ZAR\",\"native\":\"R\",\"thousands_sep\":\",\",\"decimal_sep\":\".\",\"symbol_left\":true,\"space_between\":true,\"exp\":2,\"min_amount\":\"1789\",\"max_amount\":\"17894299\"}};\n\nexport default Currencies;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {EMOJI_VERSION} from '../environment/emojiVersionsSupport';\n\nexport const EmojiVersions: {[version in EMOJI_VERSION]: {[emoji: string]: number}} = {'14':{'1f6dd':4867, '1f6de':4916, '1f6df':4923, '1f7f0':62832, '1f979':183, '1f9cc':1557, '1fa7b':61332, '1fa7c':61330, '1faa9':51093, '1faaa':61364, '1faab':61189, '1faac':51085, '1fab7':2651, '1fab8':2631, '1fab9':2672, '1faba':2673, '1fac3':1520, '1fac4':1521, '1fac5':1505, '1fad7':3793, '1fad8':3707, '1fad9':3804, '1fae0':111, '1fae1':136, '1fae2':132, '1fae3':133, '1fae4':174, '1fae5':142, '1fae6':1385, '1fae7':61353, '1faf0':1341, '1faf1':1332, '1faf2':1333, '1faf3':1334, '1faf4':1335, '1faf5':1351, '1faf6':1360, '1faf1-1f3fb-200d-1faf2-1f3fc':0, '1faf1-1f3fb-200d-1faf2-1f3fd':0, '1faf1-1f3fb-200d-1faf2-1f3fe':0, '1faf1-1f3fb-200d-1faf2-1f3ff':0, '1faf1-1f3fc-200d-1faf2-1f3fb':0, '1faf1-1f3fc-200d-1faf2-1f3fd':0, '1faf1-1f3fc-200d-1faf2-1f3fe':0, '1faf1-1f3fc-200d-1faf2-1f3ff':0, '1faf1-1f3fd-200d-1faf2-1f3fb':0, '1faf1-1f3fd-200d-1faf2-1f3fc':0, '1faf1-1f3fd-200d-1faf2-1f3fe':0, '1faf1-1f3fd-200d-1faf2-1f3ff':0, '1faf1-1f3fe-200d-1faf2-1f3fb':0, '1faf1-1f3fe-200d-1faf2-1f3fc':0, '1faf1-1f3fe-200d-1faf2-1f3fd':0, '1faf1-1f3fe-200d-1faf2-1f3ff':0, '1faf1-1f3ff-200d-1faf2-1f3fb':0, '1faf1-1f3ff-200d-1faf2-1f3fc':0, '1faf1-1f3ff-200d-1faf2-1f3fd':0, '1faf1-1f3ff-200d-1faf2-1f3fe':0, '1fac3-1f3fb':0, '1fac3-1f3fc':0, '1fac3-1f3fd':0, '1fac3-1f3fe':0, '1fac3-1f3ff':0, '1fac4-1f3fb':0, '1fac4-1f3fc':0, '1fac4-1f3fd':0, '1fac4-1f3fe':0, '1fac4-1f3ff':0, '1fac5-1f3fb':0, '1fac5-1f3fc':0, '1fac5-1f3fd':0, '1fac5-1f3fe':0, '1fac5-1f3ff':0, '1faf0-1f3fb':0, '1faf0-1f3fc':0, '1faf0-1f3fd':0, '1faf0-1f3fe':0, '1faf0-1f3ff':0, '1faf1-1f3fb':0, '1faf1-1f3fc':0, '1faf1-1f3fd':0, '1faf1-1f3fe':0, '1faf1-1f3ff':0, '1faf2-1f3fb':0, '1faf2-1f3fc':0, '1faf2-1f3fd':0, '1faf2-1f3fe':0, '1faf2-1f3ff':0, '1faf3-1f3fb':0, '1faf3-1f3fc':0, '1faf3-1f3fd':0, '1faf3-1f3fe':0, '1faf3-1f3ff':0, '1faf4-1f3fb':0, '1faf4-1f3fc':0, '1faf4-1f3fd':0, '1faf4-1f3fe':0, '1faf4-1f3ff':0, '1faf5-1f3fb':0, '1faf5-1f3fc':0, '1faf5-1f3fd':0, '1faf5-1f3fe':0, '1faf5-1f3ff':0, '1faf6-1f3fb':0, '1faf6-1f3fc':0, '1faf6-1f3fd':0, '1faf6-1f3fe':0, '1faf6-1f3ff':0}, '':{'2049':62835, '2122':62863, '2139':62888, '2194':62764, '2195':62763, '2196':62762, '2197':62756, '2198':62758, '2199':62760, '2328':61194, '2600':4990, '2601':4998, '2602':41013, '2603':41018, '2604':41020, '2611':62851, '2614':41014, '2615':3781, '2618':2667, '2620':1106, '2622':62753, '2623':62754, '2626':62783, '2638':62780, '2639':177, '2648':62788, '2649':62789, '2650':62796, '2651':62797, '2652':62798, '2653':62799, '2660':51095, '2663':51098, '2665':51096, '2666':51097, '2668':4865, '2692':61297, '2693':4922, '2694':61300, '2696':61311, '2697':61319, '2699':61309, '2702':61284, '2705':62850, '2708':4931, '2709':61245, '2712':61259, '2714':62852, '2716':62828, '2721':62779, '2728':51029, '2733':62858, '2734':62859, '2744':41017, '2747':62860, '2753':62836, '2754':62837, '2755':62838, '2757':62839, '2763':1137, '2764':1141, '2795':62829, '2796':62830, '2797':62831, '2934':62767, '2935':62768, '3030':62840, '3297':62912, '3299':62913, '0023-20e3':62864, '002a-20e3':62865, '0030-20e3':62866, '0031-20e3':62867, '0032-20e3':62868, '0033-20e3':62869, '0034-20e3':62870, '0035-20e3':62871, '0036-20e3':62872, '0037-20e3':62873, '0038-20e3':62874, '0039-20e3':62875, '00a9':62861, '00ae':62862, '1f004':51101, '1f0cf':51100, '1f170':62882, '1f171':62884, '1f17e':62893, '1f17f':62895, '1f18e':62883, '1f191':62885, '1f192':62886, '1f193':62887, '1f194':62889, '1f195':62891, '1f196':62892, '1f197':62894, '1f198':62896, '1f199':62897, '1f19a':62898, '1f1e6-1f1e8':71594, '1f1e6-1f1e9':71595, '1f1e6-1f1ea':71596, '1f1e6-1f1eb':71597, '1f1e6-1f1ec':71598, '1f1e6-1f1ee':71599, '1f1e6-1f1f1':71600, '1f1e6-1f1f2':71601, '1f1e6-1f1f4':71602, '1f1e6-1f1f6':71603, '1f1e6-1f1f7':71604, '1f1e6-1f1f8':71605, '1f1e6-1f1f9':71606, '1f1e6-1f1fa':71607, '1f1e6-1f1fc':71608, '1f1e6-1f1fd':71609, '1f1e6-1f1ff':71610, '1f1e7-1f1e6':71611, '1f1e7-1f1e7':71612, '1f1e7-1f1e9':71613, '1f1e7-1f1ea':71614, '1f1e7-1f1eb':71615, '1f1e7-1f1ec':71616, '1f1e7-1f1ed':71617, '1f1e7-1f1ee':71618, '1f1e7-1f1ef':71619, '1f1e7-1f1f1':71620, '1f1e7-1f1f2':71621, '1f1e7-1f1f3':71622, '1f1e7-1f1f4':71623, '1f1e7-1f1f6':71624, '1f1e7-1f1f7':71625, '1f1e7-1f1f8':71626, '1f1e7-1f1f9':71627, '1f1e7-1f1fb':71628, '1f1e7-1f1fc':71629, '1f1e7-1f1fe':71630, '1f1e7-1f1ff':71631, '1f1e8-1f1e6':71632, '1f1e8-1f1e8':71633, '1f1e8-1f1e9':71634, '1f1e8-1f1eb':71635, '1f1e8-1f1ec':71636, '1f1e8-1f1ed':71637, '1f1e8-1f1ee':71638, '1f1e8-1f1f0':71639, '1f1e8-1f1f1':71640, '1f1e8-1f1f2':71641, '1f1e8-1f1f3':71642, '1f1e8-1f1f4':71643, '1f1e8-1f1f5':71644, '1f1e8-1f1f7':71645, '1f1e8-1f1fa':71646, '1f1e8-1f1fb':71647, '1f1e8-1f1fc':71648, '1f1e8-1f1fd':71649, '1f1e8-1f1fe':71650, '1f1e8-1f1ff':71651, '1f1e9-1f1ea':71652, '1f1e9-1f1ec':71653, '1f1e9-1f1ef':71654, '1f1e9-1f1f0':71655, '1f1e9-1f1f2':71656, '1f1e9-1f1f4':71657, '1f1e9-1f1ff':71658, '1f1ea-1f1e6':71659, '1f1ea-1f1e8':71660, '1f1ea-1f1ea':71661, '1f1ea-1f1ec':71662, '1f1ea-1f1ed':71663, '1f1ea-1f1f7':71664, '1f1ea-1f1f8':71665, '1f1ea-1f1f9':71666, '1f1ea-1f1fa':71667, '1f1eb-1f1ee':71668, '1f1eb-1f1ef':71669, '1f1eb-1f1f0':71670, '1f1eb-1f1f2':71671, '1f1eb-1f1f4':71672, '1f1eb-1f1f7':71673, '1f1ec-1f1e6':71674, '1f1ec-1f1e7':71675, '1f1ec-1f1e9':71676, '1f1ec-1f1ea':71677, '1f1ec-1f1eb':71678, '1f1ec-1f1ec':71679, '1f1ec-1f1ed':71680, '1f1ec-1f1ee':71681, '1f1ec-1f1f1':71682, '1f1ec-1f1f2':71683, '1f1ec-1f1f3':71684, '1f1ec-1f1f5':71685, '1f1ec-1f1f6':71686, '1f1ec-1f1f7':71687, '1f1ec-1f1f8':71688, '1f1ec-1f1f9':71689, '1f1ec-1f1fa':71690, '1f1ec-1f1fc':71691, '1f1ec-1f1fe':71692, '1f1ed-1f1f0':71693, '1f1ed-1f1f2':71694, '1f1ed-1f1f3':71695, '1f1ed-1f1f7':71696, '1f1ed-1f1f9':71697, '1f1ed-1f1fa':71698, '1f1ee-1f1e8':71699, '1f1ee-1f1e9':71700, '1f1ee-1f1ea':71701, '1f1ee-1f1f1':71702, '1f1ee-1f1f2':71703, '1f1ee-1f1f3':71704, '1f1ee-1f1f4':71705, '1f1ee-1f1f6':71706, '1f1ee-1f1f7':71707, '1f1ee-1f1f8':71708, '1f1ee-1f1f9':71709, '1f1ef-1f1ea':71710, '1f1ef-1f1f2':71711, '1f1ef-1f1f4':71712, '1f1ef-1f1f5':71713, '1f1f0-1f1ea':71714, '1f1f0-1f1ec':71715, '1f1f0-1f1ed':71716, '1f1f0-1f1ee':71717, '1f1f0-1f1f2':71718, '1f1f0-1f1f3':71719, '1f1f0-1f1f5':71720, '1f1f0-1f1f7':71721, '1f1f0-1f1fc':71722, '1f1f0-1f1fe':71723, '1f1f0-1f1ff':71724, '1f1f1-1f1e6':71725, '1f1f1-1f1e7':71726, '1f1f1-1f1e8':71727, '1f1f1-1f1ee':71728, '1f1f1-1f1f0':71729, '1f1f1-1f1f7':71730, '1f1f1-1f1f8':71731, '1f1f1-1f1f9':71732, '1f1f1-1f1fa':71733, '1f1f1-1f1fb':71734, '1f1f1-1f1fe':71735, '1f1f2-1f1e6':71736, '1f1f2-1f1e8':71737, '1f1f2-1f1e9':71738, '1f1f2-1f1ea':71739, '1f1f2-1f1eb':71740, '1f1f2-1f1ec':71741, '1f1f2-1f1ed':71742, '1f1f2-1f1f0':71743, '1f1f2-1f1f1':71744, '1f1f2-1f1f2':71745, '1f1f2-1f1f3':71746, '1f1f2-1f1f4':71747, '1f1f2-1f1f5':71748, '1f1f2-1f1f6':71749, '1f1f2-1f1f7':71750, '1f1f2-1f1f8':71751, '1f1f2-1f1f9':71752, '1f1f2-1f1fa':71753, '1f1f2-1f1fb':71754, '1f1f2-1f1fc':71755, '1f1f2-1f1fd':71756, '1f1f2-1f1fe':71757, '1f1f2-1f1ff':71758, '1f1f3-1f1e6':71759, '1f1f3-1f1e8':71760, '1f1f3-1f1ea':71761, '1f1f3-1f1eb':71762, '1f1f3-1f1ec':71763, '1f1f3-1f1ee':71764, '1f1f3-1f1f1':71765, '1f1f3-1f1f4':71766, '1f1f3-1f1f5':71767, '1f1f3-1f1f7':71768, '1f1f3-1f1fa':71769, '1f1f3-1f1ff':71770, '1f1f4-1f1f2':71771, '1f1f5-1f1e6':71772, '1f1f5-1f1ea':71773, '1f1f5-1f1eb':71774, '1f1f5-1f1ec':71775, '1f1f5-1f1ed':71776, '1f1f5-1f1f0':71777, '1f1f5-1f1f1':71778, '1f1f5-1f1f2':71779, '1f1f5-1f1f3':71780, '1f1f5-1f1f7':71781, '1f1f5-1f1f8':71782, '1f1f5-1f1f9':71783, '1f1f5-1f1fc':71784, '1f1f5-1f1fe':71785, '1f1f6-1f1e6':71786, '1f1f7-1f1ea':71787, '1f1f7-1f1f4':71788, '1f1f7-1f1f8':71789, '1f1f7-1f1fa':71790, '1f1f7-1f1fc':71791, '1f1f8-1f1e6':71792, '1f1f8-1f1e7':71793, '1f1f8-1f1e8':71794, '1f1f8-1f1e9':71795, '1f1f8-1f1ea':71796, '1f1f8-1f1ec':71797, '1f1f8-1f1ed':71798, '1f1f8-1f1ee':71799, '1f1f8-1f1ef':71800, '1f1f8-1f1f0':71801, '1f1f8-1f1f1':71802, '1f1f8-1f1f2':71803, '1f1f8-1f1f3':71804, '1f1f8-1f1f4':71805, '1f1f8-1f1f7':71806, '1f1f8-1f1f8':71807, '1f1f8-1f1f9':71808, '1f1f8-1f1fb':71809, '1f1f8-1f1fd':71810, '1f1f8-1f1fe':71811, '1f1f8-1f1ff':71812, '1f1f9-1f1e6':71813, '1f1f9-1f1e8':71814, '1f1f9-1f1e9':71815, '1f1f9-1f1eb':71816, '1f1f9-1f1ec':71817, '1f1f9-1f1ed':71818, '1f1f9-1f1ef':71819, '1f1f9-1f1f0':71820, '1f1f9-1f1f1':71821, '1f1f9-1f1f2':71822, '1f1f9-1f1f3':71823, '1f1f9-1f1f4':71824, '1f1f9-1f1f7':71825, '1f1f9-1f1f9':71826, '1f1f9-1f1fb':71827, '1f1f9-1f1fc':71828, '1f1f9-1f1ff':71829, '1f1fa-1f1e6':71830, '1f1fa-1f1ec':71831, '1f1fa-1f1f2':71832, '1f1fa-1f1f3':71833, '1f1fa-1f1f8':71834, '1f1fa-1f1fe':71835, '1f1fa-1f1ff':71836, '1f1fb-1f1e6':71837, '1f1fb-1f1e8':71838, '1f1fb-1f1ea':71839, '1f1fb-1f1ec':71840, '1f1fb-1f1ee':71841, '1f1fb-1f1f3':71842, '1f1fb-1f1fa':71843, '1f1fc-1f1eb':71844, '1f1fc-1f1f8':71845, '1f1fd-1f1f0':71846, '1f1fe-1f1ea':71847, '1f1fe-1f1f9':71848, '1f1ff-1f1e6':71849, '1f1ff-1f1f2':71850, '1f1ff-1f1fc':71851, '1f201':62899, '1f202':62900, '1f21a':62906, '1f22f':62903, '1f232':62907, '1f233':62911, '1f234':62910, '1f235':62915, '1f236':62902, '1f237':62901, '1f238':62909, '1f239':62905, '1f23a':62914, '1f250':62904, '1f251':62908, '1f300':41010, '1f301':4857, '1f302':41012, '1f303':4858, '1f304':4860, '1f305':4861, '1f306':4862, '1f307':4863, '1f308':41011, '1f309':4864, '1f30a':41023, '1f30b':4815, '1f30c':4997, '1f30d':4806, '1f30e':4807, '1f30f':4808, '1f310':4809, '1f311':4977, '1f312':4978, '1f313':4979, '1f314':4980, '1f315':4981, '1f316':4982, '1f317':4983, '1f318':4984, '1f319':4985, '1f31a':4986, '1f31b':4987, '1f31c':4988, '1f31d':4991, '1f31e':4992, '1f31f':4995, '1f320':4996, '1f321':4989, '1f324':41001, '1f325':41002, '1f326':41003, '1f327':41004, '1f328':41005, '1f329':41006, '1f32a':41007, '1f32b':41008, '1f32c':41009, '1f32d':3725, '1f32e':3727, '1f32f':3728, '1f330':3708, '1f331':2659, '1f332':2661, '1f333':2662, '1f334':2663, '1f335':2664, '1f336':3698, '1f337':2658, '1f338':2649, '1f339':2653, '1f33a':2655, '1f33b':2656, '1f33c':2657, '1f33d':3697, '1f33e':2665, '1f33f':2666, '1f340':2668, '1f341':2669, '1f342':2670, '1f343':2671, '1f344':3705, '1f345':3690, '1f346':3694, '1f347':3674, '1f348':3675, '1f349':3676, '1f34a':3677, '1f34b':3678, '1f34c':3679, '1f34d':3680, '1f34e':3682, '1f34f':3683, '1f350':3684, '1f351':3685, '1f352':3686, '1f353':3687, '1f354':3722, '1f355':3724, '1f356':3718, '1f357':3719, '1f358':3744, '1f359':3745, '1f35a':3746, '1f35b':3747, '1f35c':3748, '1f35d':3749, '1f35e':3709, '1f35f':3723, '1f360':3750, '1f361':3756, '1f362':3751, '1f363':3752, '1f364':3753, '1f365':3754, '1f366':3765, '1f367':3766, '1f368':3767, '1f369':3768, '1f36a':3769, '1f36b':3774, '1f36c':3775, '1f36d':3776, '1f36e':3777, '1f36f':3778, '1f370':3771, '1f371':3743, '1f372':3735, '1f373':3733, '1f374':3801, '1f375':3783, '1f376':3784, '1f377':3786, '1f378':3787, '1f379':3788, '1f37a':3789, '1f37b':3790, '1f37c':3779, '1f37d':3800, '1f37e':3785, '1f37f':3739, '1f380':51040, '1f381':51041, '1f382':3770, '1f383':51024, '1f384':51025, '1f385':1527, '1f386':51026, '1f387':51027, '1f388':51030, '1f389':51031, '1f38a':51032, '1f38b':51033, '1f38c':71588, '1f38d':51034, '1f38e':51035, '1f38f':51036, '1f390':51037, '1f391':51038, '1f392':61134, '1f393':61147, '1f396':51045, '1f397':51042, '1f399':61167, '1f39a':61168, '1f39b':61169, '1f39e':61203, '1f39f':51043, '1f3a0':4866, '1f3a1':4868, '1f3a2':4869, '1f3a3':51072, '1f3a4':61170, '1f3a5':61202, '1f3a6':62819, '1f3a7':61171, '1f3a8':51105, '1f3a9':61146, '1f3aa':4871, '1f3ab':51044, '1f3ac':61205, '1f3ad':51103, '1f3ae':51086, '1f3af':51078, '1f3b0':51088, '1f3b1':51081, '1f3b2':51089, '1f3b3':51060, '1f3b4':51102, '1f3b5':61165, '1f3b6':61166, '1f3b7':61173, '1f3b8':61175, '1f3b9':61176, '1f3ba':61177, '1f3bb':61178, '1f3bc':61164, '1f3bd':51074, '1f3be':51058, '1f3bf':51075, '1f3c0':51054, '1f3c1':71586, '1f3c2':1600, '1f3c3-200d-2640':1584, '1f3c3-200d-2642':1583, '1f3c3':1582, '1f3c4-200d-2640':1606, '1f3c4-200d-2642':1605, '1f3c4':1604, '1f3c5':51047, '1f3c6':51046, '1f3c7':1598, '1f3c8':51056, '1f3c9':51057, '1f3ca-200d-2640':1612, '1f3ca-200d-2642':1611, '1f3ca':1610, '1f3cb-200d-2640':1618, '1f3cb-200d-2642':1617, '1f3cb':1616, '1f3cc-200d-2640':1603, '1f3cc-200d-2642':1602, '1f3cc':1601, '1f3cd':4902, '1f3ce':4901, '1f3cf':51061, '1f3d0':51055, '1f3d1':51062, '1f3d2':51063, '1f3d3':51065, '1f3d4':4813, '1f3d5':4817, '1f3d6':4818, '1f3d7':4824, '1f3d8':4829, '1f3d9':4859, '1f3da':4830, '1f3db':4823, '1f3dc':4819, '1f3dd':4820, '1f3de':4821, '1f3df':4822, '1f3e0':4831, '1f3e1':4832, '1f3e2':4833, '1f3e3':4834, '1f3e4':4835, '1f3e5':4836, '1f3e6':4837, '1f3e7':62729, '1f3e8':4838, '1f3e9':4839, '1f3ea':4840, '1f3eb':4841, '1f3ec':4842, '1f3ed':4843, '1f3ee':61216, '1f3ef':4844, '1f3f0':4845, '1f3f3-200d-1f308':71591, '1f3f3-200d-26a7':71592, '1f3f3':71590, '1f3f4-200d-2620':71593, '1f3f4-e0067-e0062-e0065-e006e-e0067-e007f':71852, '1f3f4-e0067-e0062-e0073-e0063-e0074-e007f':71853, '1f3f4-e0067-e0062-e0077-e006c-e0073-e007f':71854, '1f3f4':71589, '1f3f5':2652, '1f3f7':61234, '1f3f8':51066, '1f3f9':61303, '1f3fa':3805, '1f3fb':9525, '1f3fc':9526, '1f3fd':9527, '1f3fe':9528, '1f3ff':9529, '1f400':2576, '1f401':2575, '1f402':2556, '1f403':2557, '1f404':2558, '1f405':2547, '1f406':2548, '1f407':2579, '1f408-200d-2b1b':2544, '1f408':2543, '1f409':2618, '1f40a':2613, '1f40b':2622, '1f40c':2632, '1f40d':2616, '1f40e':2550, '1f40f':2563, '1f410':2565, '1f411':2564, '1f412':2531, '1f413':2596, '1f414':2595, '1f415-200d-1f9ba':2537, '1f415':2535, '1f416':2560, '1f417':2561, '1f418':2570, '1f419':2629, '1f41a':2630, '1f41b':2634, '1f41c':2635, '1f41d':2636, '1f41e':2638, '1f41f':2625, '1f420':2626, '1f421':2627, '1f422':2614, '1f423':2597, '1f424':2598, '1f425':2599, '1f426':2600, '1f427':2601, '1f428':2586, '1f429':2538, '1f42a':2566, '1f42b':2567, '1f42c':2623, '1f42d':2574, '1f42e':2555, '1f42f':2546, '1f430':2578, '1f431':2542, '1f432':2617, '1f433':2621, '1f434':2549, '1f435':2530, '1f436':2534, '1f437':2559, '1f438':2612, '1f439':2577, '1f43a':2539, '1f43b-200d-2744':2585, '1f43b':2584, '1f43c':2587, '1f43d':2562, '1f43e':2593, '1f43f':2580, '1f440':1381, '1f441-200d-1f5e8':1159, '1f441':1382, '1f442':1373, '1f443':1375, '1f444':1384, '1f445':1383, '1f446':1347, '1f447':1349, '1f448':1345, '1f449':1346, '1f44a':1355, '1f44b':1327, '1f44c':1336, '1f44d':1352, '1f44e':1353, '1f44f':1358, '1f450':1361, '1f451':61144, '1f452':61145, '1f453':61110, '1f454':61115, '1f455':61116, '1f456':61117, '1f457':61122, '1f458':61123, '1f459':61128, '1f45a':61129, '1f45b':61130, '1f45c':61131, '1f45d':61132, '1f45e':61136, '1f45f':61137, '1f460':61140, '1f461':61141, '1f462':61143, '1f463':1687, '1f464':1684, '1f465':1685, '1f466':1388, '1f467':1389, '1f468-200d-1f33e':1457, '1f468-200d-1f373':1460, '1f468-200d-1f37c':1524, '1f468-200d-1f393':1448, '1f468-200d-1f3a4':1478, '1f468-200d-1f3a8':1481, '1f468-200d-1f3eb':1451, '1f468-200d-1f3ed':1466, '1f468-200d-1f466-200d-1f466':1674, '1f468-200d-1f466':1673, '1f468-200d-1f467-200d-1f466':1676, '1f468-200d-1f467-200d-1f467':1677, '1f468-200d-1f467':1675, '1f468-200d-1f468-200d-1f466':1663, '1f468-200d-1f468-200d-1f466-200d-1f466':1666, '1f468-200d-1f468-200d-1f467':1664, '1f468-200d-1f468-200d-1f467-200d-1f466':1665, '1f468-200d-1f468-200d-1f467-200d-1f467':1667, '1f468-200d-1f469-200d-1f466':1658, '1f468-200d-1f469-200d-1f466-200d-1f466':1661, '1f468-200d-1f469-200d-1f467':1659, '1f468-200d-1f469-200d-1f467-200d-1f466':1660, '1f468-200d-1f469-200d-1f467-200d-1f467':1662, '1f468-200d-1f4bb':1475, '1f468-200d-1f4bc':1469, '1f468-200d-1f527':1463, '1f468-200d-1f52c':1472, '1f468-200d-1f680':1487, '1f468-200d-1f692':1490, '1f468-200d-1f9af':1574, '1f468-200d-1f9b0':1396, '1f468-200d-1f9b1':1397, '1f468-200d-1f9b2':1399, '1f468-200d-1f9b3':1398, '1f468-200d-1f9bc':1577, '1f468-200d-1f9bd':1580, '1f468-200d-2695':1445, '1f468-200d-2696':1454, '1f468-200d-2708':1484, '1f468-200d-2764-200d-1f468':1655, '1f468-200d-2764-200d-1f48b-200d-1f468':1651, '1f468':1392, '1f469-200d-1f33e':1458, '1f469-200d-1f373':1461, '1f469-200d-1f37c':1523, '1f469-200d-1f393':1449, '1f469-200d-1f3a4':1479, '1f469-200d-1f3a8':1482, '1f469-200d-1f3eb':1452, '1f469-200d-1f3ed':1467, '1f469-200d-1f466-200d-1f466':1679, '1f469-200d-1f466':1678, '1f469-200d-1f467-200d-1f466':1681, '1f469-200d-1f467-200d-1f467':1682, '1f469-200d-1f467':1680, '1f469-200d-1f469-200d-1f466':1668, '1f469-200d-1f469-200d-1f466-200d-1f466':1671, '1f469-200d-1f469-200d-1f467':1669, '1f469-200d-1f469-200d-1f467-200d-1f466':1670, '1f469-200d-1f469-200d-1f467-200d-1f467':1672, '1f469-200d-1f4bb':1476, '1f469-200d-1f4bc':1470, '1f469-200d-1f527':1464, '1f469-200d-1f52c':1473, '1f469-200d-1f680':1488, '1f469-200d-1f692':1491, '1f469-200d-1f9af':1575, '1f469-200d-1f9b0':1401, '1f469-200d-1f9b1':1403, '1f469-200d-1f9b2':1407, '1f469-200d-1f9b3':1405, '1f469-200d-1f9bc':1578, '1f469-200d-1f9bd':1581, '1f469-200d-2695':1446, '1f469-200d-2696':1455, '1f469-200d-2708':1485, '1f469-200d-2764-200d-1f468':1654, '1f469-200d-2764-200d-1f469':1656, '1f469-200d-2764-200d-1f48b-200d-1f468':1650, '1f469-200d-2764-200d-1f48b-200d-1f469':1652, '1f469':1400, '1f46a':1657, '1f46b':1647, '1f46c':1648, '1f46d':1646, '1f46e-200d-2640':1494, '1f46e-200d-2642':1493, '1f46e':1492, '1f46f-200d-2640':1590, '1f46f-200d-2642':1589, '1f46f':1588, '1f470-200d-2640':1518, '1f470-200d-2642':1517, '1f470':1516, '1f471-200d-2640':1409, '1f471-200d-2642':1410, '1f471':1391, '1f472':1511, '1f473-200d-2640':1510, '1f473-200d-2642':1509, '1f473':1508, '1f474':1412, '1f475':1413, '1f476':1386, '1f477-200d-2640':1504, '1f477-200d-2642':1503, '1f477':1502, '1f478':1507, '1f479':1109, '1f47a':1110, '1f47b':1111, '1f47c':1526, '1f47d':1112, '1f47e':1113, '1f47f':1104, '1f480':1105, '1f481-200d-2640':1428, '1f481-200d-2642':1427, '1f481':1426, '1f482-200d-2640':1500, '1f482-200d-2642':1499, '1f482':1498, '1f483':1585, '1f484':61152, '1f485':1366, '1f486-200d-2640':1560, '1f486-200d-2642':1559, '1f486':1558, '1f487-200d-2640':1563, '1f487-200d-2642':1562, '1f487':1561, '1f488':4870, '1f489':61326, '1f48a':61328, '1f48b':1127, '1f48c':1128, '1f48d':61153, '1f48e':61154, '1f48f':1649, '1f490':2648, '1f491':1653, '1f492':4846, '1f493':1133, '1f494':1138, '1f495':1135, '1f496':1131, '1f497':1132, '1f498':1129, '1f499':1145, '1f49a':1144, '1f49b':1143, '1f49c':1146, '1f49d':1130, '1f49e':1134, '1f49f':1136, '1f4a0':62946, '1f4a1':61214, '1f4a2':1151, '1f4a3':1157, '1f4a4':1163, '1f4a5':1152, '1f4a6':1154, '1f4a7':41022, '1f4a8':1155, '1f4a9':1107, '1f4aa':1368, '1f4ab':1153, '1f4ac':1158, '1f4ad':1162, '1f4ae':2650, '1f4af':1150, '1f4b0':61235, '1f4b1':62841, '1f4b2':62842, '1f4b3':61242, '1f4b4':61237, '1f4b5':61238, '1f4b6':61239, '1f4b7':61240, '1f4b8':61241, '1f4b9':61244, '1f4ba':4936, '1f4bb':61191, '1f4bc':61265, '1f4bd':61197, '1f4be':61198, '1f4bf':61199, '1f4c0':61200, '1f4c1':61266, '1f4c2':61267, '1f4c3':61227, '1f4c4':61229, '1f4c5':61269, '1f4c6':61270, '1f4c7':61273, '1f4c8':61274, '1f4c9':61275, '1f4ca':61276, '1f4cb':61277, '1f4cc':61278, '1f4cd':61279, '1f4ce':61280, '1f4cf':61282, '1f4d0':61283, '1f4d1':61232, '1f4d2':61226, '1f4d3':61225, '1f4d4':61218, '1f4d5':61219, '1f4d6':61220, '1f4d7':61221, '1f4d8':61222, '1f4d9':61223, '1f4da':61224, '1f4db':62847, '1f4dc':61228, '1f4dd':61264, '1f4de':61185, '1f4df':61186, '1f4e0':61187, '1f4e1':61325, '1f4e2':61159, '1f4e3':61160, '1f4e4':61249, '1f4e5':61250, '1f4e6':61251, '1f4e7':61246, '1f4e8':61247, '1f4e9':61248, '1f4ea':61253, '1f4eb':61252, '1f4ec':61254, '1f4ed':61255, '1f4ee':61256, '1f4ef':61161, '1f4f0':61230, '1f4f1':61182, '1f4f2':61183, '1f4f3':62823, '1f4f4':62824, '1f4f5':62751, '1f4f6':62822, '1f4f7':61207, '1f4f8':61208, '1f4f9':61209, '1f4fa':61206, '1f4fb':61172, '1f4fc':61210, '1f4fd':61204, '1f4ff':61151, '1f500':62801, '1f501':62802, '1f502':62803, '1f503':62769, '1f504':62770, '1f505':62820, '1f506':62821, '1f507':61155, '1f508':61156, '1f509':61157, '1f50a':61158, '1f50b':61188, '1f50c':61190, '1f50d':61211, '1f50e':61212, '1f50f':61290, '1f510':61291, '1f511':61292, '1f512':61288, '1f513':61289, '1f514':61162, '1f515':61163, '1f516':61233, '1f517':61313, '1f518':62947, '1f519':62771, '1f51a':62772, '1f51b':62773, '1f51c':62774, '1f51d':62775, '1f51e':62752, '1f51f':62876, '1f520':62877, '1f521':62878, '1f522':62879, '1f523':62880, '1f524':62881, '1f525':41021, '1f526':61215, '1f527':61306, '1f528':61294, '1f529':61308, '1f52a':3803, '1f52b':61301, '1f52c':61323, '1f52d':61324, '1f52e':51082, '1f52f':62787, '1f530':62848, '1f531':62846, '1f532':62949, '1f533':62948, '1f534':62916, '1f535':62920, '1f536':62940, '1f537':62941, '1f538':62942, '1f539':62943, '1f53a':62944, '1f53b':62945, '1f53c':62811, '1f53d':62813, '1f549':62778, '1f54a':2602, '1f54b':4854, '1f54c':4850, '1f54d':4852, '1f54e':62786, '1f550':4955, '1f551':4957, '1f552':4959, '1f553':4961, '1f554':4963, '1f555':4965, '1f556':4967, '1f557':4969, '1f558':4971, '1f559':4973, '1f55a':4975, '1f55b':4953, '1f55c':4956, '1f55d':4958, '1f55e':4960, '1f55f':4962, '1f560':4964, '1f561':4966, '1f562':4968, '1f563':4970, '1f564':4972, '1f565':4974, '1f566':4976, '1f567':4954, '1f56f':61213, '1f570':4952, '1f573':1156, '1f574':1587, '1f575-200d-2640':1497, '1f575-200d-2642':1496, '1f575':1495, '1f576':61111, '1f577':2641, '1f578':2642, '1f579':51087, '1f57a':1586, '1f587':61281, '1f58a':61261, '1f58b':61260, '1f58c':61262, '1f58d':61263, '1f590':1329, '1f595':1348, '1f596':1331, '1f5a4':1148, '1f5a5':61192, '1f5a8':61193, '1f5b1':61195, '1f5b2':61196, '1f5bc':51104, '1f5c2':61268, '1f5c3':61285, '1f5c4':61286, '1f5d1':61287, '1f5d2':61271, '1f5d3':61272, '1f5dc':61310, '1f5dd':61293, '1f5de':61231, '1f5e1':61299, '1f5e3':1683, '1f5e8':1160, '1f5ef':1161, '1f5f3':61257, '1f5fa':4810, '1f5fb':4816, '1f5fc':4847, '1f5fd':4848, '1f5fe':4811, '1f5ff':61362, '1f600':11, '1f601':14, '1f602':18, '1f603':12, '1f604':13, '1f605':16, '1f606':15, '1f607':114, '1f608':1103, '1f609':112, '1f60a':113, '1f60b':124, '1f60c':150, '1f60d':116, '1f60e':170, '1f60f':144, '1f610':139, '1f611':140, '1f612':145, '1f613':195, '1f614':151, '1f615':173, '1f616':192, '1f617':119, '1f618':118, '1f619':122, '1f61a':121, '1f61b':125, '1f61c':126, '1f61d':128, '1f61e':194, '1f61f':175, '1f620':1101, '1f621':1100, '1f622':189, '1f623':193, '1f624':199, '1f625':188, '1f626':184, '1f627':185, '1f628':186, '1f629':196, '1f62a':152, '1f62b':197, '1f62c':147, '1f62d':190, '1f62e-200d-1f4a8':148, '1f62e':178, '1f62f':179, '1f630':187, '1f631':191, '1f632':180, '1f633':181, '1f634':154, '1f635-200d-1f4ab':165, '1f635':164, '1f636-200d-1f32b':143, '1f636':141, '1f637':155, '1f638':1116, '1f639':1117, '1f63a':1115, '1f63b':1118, '1f63c':1119, '1f63d':1120, '1f63e':1123, '1f63f':1122, '1f640':1121, '1f641':176, '1f642':19, '1f643':110, '1f644':146, '1f645-200d-2640':1422, '1f645-200d-2642':1421, '1f645':1420, '1f646-200d-2640':1425, '1f646-200d-2642':1424, '1f646':1423, '1f647-200d-2640':1437, '1f647-200d-2642':1436, '1f647':1435, '1f648':1124, '1f649':1125, '1f64a':1126, '1f64b-200d-2640':1431, '1f64b-200d-2642':1430, '1f64b':1429, '1f64c':1359, '1f64d-200d-2640':1416, '1f64d-200d-2642':1415, '1f64d':1414, '1f64e-200d-2640':1419, '1f64e-200d-2642':1418, '1f64e':1417, '1f64f':1364, '1f680':4942, '1f681':4937, '1f682':4872, '1f683':4873, '1f684':4874, '1f685':4875, '1f686':4876, '1f687':4877, '1f688':4878, '1f689':4879, '1f68a':4880, '1f68b':4883, '1f68c':4884, '1f68d':4885, '1f68e':4886, '1f68f':4911, '1f690':4887, '1f691':4888, '1f692':4889, '1f693':4890, '1f694':4891, '1f695':4892, '1f696':4893, '1f697':4894, '1f698':4895, '1f699':4896, '1f69a':4898, '1f69b':4899, '1f69c':4900, '1f69d':4881, '1f69e':4882, '1f69f':4938, '1f6a0':4939, '1f6a1':4940, '1f6a2':4930, '1f6a3-200d-2640':1609, '1f6a3-200d-2642':1608, '1f6a3':1607, '1f6a4':4926, '1f6a5':4918, '1f6a6':4919, '1f6a7':4921, '1f6a8':4917, '1f6a9':71587, '1f6aa':61333, '1f6ab':62745, '1f6ac':61358, '1f6ad':62747, '1f6ae':62730, '1f6af':62748, '1f6b0':62731, '1f6b1':62749, '1f6b2':4907, '1f6b3':62746, '1f6b4-200d-2640':1621, '1f6b4-200d-2642':1620, '1f6b4':1619, '1f6b5-200d-2640':1624, '1f6b5-200d-2642':1623, '1f6b5':1622, '1f6b6-200d-2640':1566, '1f6b6-200d-2642':1565, '1f6b6':1564, '1f6b7':62750, '1f6b8':62743, '1f6b9':62733, '1f6ba':62734, '1f6bb':62735, '1f6bc':62736, '1f6bd':61340, '1f6be':62737, '1f6bf':61342, '1f6c0':1643, '1f6c1':61343, '1f6c2':62738, '1f6c3':62739, '1f6c4':62740, '1f6c5':62741, '1f6cb':61338, '1f6cc':1644, '1f6cd':61133, '1f6ce':4944, '1f6cf':61337, '1f6d0':62776, '1f6d1':4920, '1f6d2':61357, '1f6d5':4851, '1f6d6':4828, '1f6d7':61334, '1f6e0':61298, '1f6e1':61304, '1f6e2':4914, '1f6e3':4912, '1f6e4':4913, '1f6e5':4929, '1f6e9':4932, '1f6eb':4933, '1f6ec':4934, '1f6f0':4941, '1f6f3':4927, '1f6f4':4908, '1f6f5':4903, '1f6f6':4925, '1f6f7':51076, '1f6f8':4943, '1f6f9':4909, '1f6fa':4906, '1f6fb':4897, '1f6fc':4910, '1f7e0':62917, '1f7e1':62918, '1f7e2':62919, '1f7e3':62921, '1f7e4':62922, '1f7e5':62925, '1f7e6':62929, '1f7e7':62926, '1f7e8':62927, '1f7e9':62928, '1f7ea':62930, '1f7eb':62931, '1f90c':1337, '1f90d':1149, '1f90e':1147, '1f90f':1338, '1f910':137, '1f911':129, '1f912':156, '1f913':171, '1f914':135, '1f915':157, '1f916':1114, '1f917':130, '1f918':1343, '1f919':1344, '1f91a':1328, '1f91b':1356, '1f91c':1357, '1f91d':1363, '1f91e':1340, '1f91f':1342, '1f920':167, '1f921':1108, '1f922':158, '1f923':17, '1f924':153, '1f925':149, '1f926-200d-2640':1440, '1f926-200d-2642':1439, '1f926':1438, '1f927':160, '1f928':138, '1f929':117, '1f92a':127, '1f92b':134, '1f92c':1102, '1f92d':131, '1f92e':159, '1f92f':166, '1f930':1519, '1f931':1522, '1f932':1362, '1f933':1367, '1f934':1506, '1f935-200d-2640':1515, '1f935-200d-2642':1514, '1f935':1513, '1f936':1528, '1f937-200d-2640':1443, '1f937-200d-2642':1442, '1f937':1441, '1f938-200d-2640':1627, '1f938-200d-2642':1626, '1f938':1625, '1f939-200d-2640':1639, '1f939-200d-2642':1638, '1f939':1637, '1f93a':1597, '1f93c-200d-2640':1630, '1f93c-200d-2642':1629, '1f93c':1628, '1f93d-200d-2640':1633, '1f93d-200d-2642':1632, '1f93d':1631, '1f93e-200d-2640':1636, '1f93e-200d-2642':1635, '1f93e':1634, '1f93f':51073, '1f940':2654, '1f941':61180, '1f942':3791, '1f943':3792, '1f944':3802, '1f945':51069, '1f947':51048, '1f948':51049, '1f949':51050, '1f94a':51067, '1f94b':51068, '1f94c':51077, '1f94d':51064, '1f94e':51053, '1f94f':51059, '1f950':3710, '1f951':3693, '1f952':3700, '1f953':3721, '1f954':3695, '1f955':3696, '1f956':3711, '1f957':3738, '1f958':3734, '1f959':3730, '1f95a':3732, '1f95b':3780, '1f95c':3706, '1f95d':3689, '1f95e':3715, '1f95f':3757, '1f960':3758, '1f961':3759, '1f962':3799, '1f963':3737, '1f964':3794, '1f965':3692, '1f966':3702, '1f967':3773, '1f968':3713, '1f969':3720, '1f96a':3726, '1f96b':3742, '1f96c':3701, '1f96d':3681, '1f96e':3755, '1f96f':3714, '1f970':115, '1f971':198, '1f972':123, '1f973':168, '1f974':163, '1f975':161, '1f976':162, '1f977':1501, '1f978':169, '1f97a':182, '1f97b':61124, '1f97c':61113, '1f97d':61112, '1f97e':61138, '1f97f':61139, '1f980':3760, '1f981':2545, '1f982':2643, '1f983':2594, '1f984':2551, '1f985':2603, '1f986':2604, '1f987':2583, '1f988':2628, '1f989':2606, '1f98a':2540, '1f98b':2633, '1f98c':2553, '1f98d':2532, '1f98e':2615, '1f98f':2572, '1f990':3762, '1f991':3763, '1f992':2569, '1f993':2552, '1f994':2582, '1f995':2619, '1f996':2620, '1f997':2639, '1f998':2591, '1f999':2568, '1f99a':2610, '1f99b':2573, '1f99c':2611, '1f99d':2541, '1f99e':3761, '1f99f':2644, '1f9a0':2647, '1f9a1':2592, '1f9a2':2605, '1f9a3':2571, '1f9a4':2607, '1f9a5':2588, '1f9a6':2589, '1f9a7':2533, '1f9a8':2590, '1f9a9':2609, '1f9aa':3764, '1f9ab':2581, '1f9ac':2554, '1f9ad':2624, '1f9ae':2536, '1f9af':61312, '1f9b4':1380, '1f9b5':1371, '1f9b6':1372, '1f9b7':1379, '1f9b8-200d-2640':1532, '1f9b8-200d-2642':1531, '1f9b8':1530, '1f9b9-200d-2640':1535, '1f9b9-200d-2642':1534, '1f9b9':1533, '1f9ba':61114, '1f9bb':1374, '1f9bc':4905, '1f9bd':4904, '1f9be':1369, '1f9bf':1370, '1f9c0':3717, '1f9c1':3772, '1f9c2':3741, '1f9c3':3796, '1f9c4':3703, '1f9c5':3704, '1f9c6':3731, '1f9c7':3716, '1f9c8':3740, '1f9c9':3797, '1f9ca':3798, '1f9cb':3795, '1f9cd-200d-2640':1569, '1f9cd-200d-2642':1568, '1f9cd':1567, '1f9ce-200d-2640':1572, '1f9ce-200d-2642':1571, '1f9ce':1570, '1f9cf-200d-2640':1434, '1f9cf-200d-2642':1433, '1f9cf':1432, '1f9d0':172, '1f9d1-200d-1f33e':1456, '1f9d1-200d-1f373':1459, '1f9d1-200d-1f37c':1525, '1f9d1-200d-1f384':1529, '1f9d1-200d-1f393':1447, '1f9d1-200d-1f3a4':1477, '1f9d1-200d-1f3a8':1480, '1f9d1-200d-1f3eb':1450, '1f9d1-200d-1f3ed':1465, '1f9d1-200d-1f4bb':1474, '1f9d1-200d-1f4bc':1468, '1f9d1-200d-1f527':1462, '1f9d1-200d-1f52c':1471, '1f9d1-200d-1f680':1486, '1f9d1-200d-1f692':1489, '1f9d1-200d-1f91d-200d-1f9d1':1645, '1f9d1-200d-1f9af':1573, '1f9d1-200d-1f9b0':1402, '1f9d1-200d-1f9b1':1404, '1f9d1-200d-1f9b2':1408, '1f9d1-200d-1f9b3':1406, '1f9d1-200d-1f9bc':1576, '1f9d1-200d-1f9bd':1579, '1f9d1-200d-2695':1444, '1f9d1-200d-2696':1453, '1f9d1-200d-2708':1483, '1f9d1':1390, '1f9d2':1387, '1f9d3':1411, '1f9d4-200d-2640':1395, '1f9d4-200d-2642':1394, '1f9d4':1393, '1f9d5':1512, '1f9d6-200d-2640':1593, '1f9d6-200d-2642':1592, '1f9d6':1591, '1f9d7-200d-2640':1596, '1f9d7-200d-2642':1595, '1f9d7':1594, '1f9d8-200d-2640':1642, '1f9d8-200d-2642':1641, '1f9d8':1640, '1f9d9-200d-2640':1538, '1f9d9-200d-2642':1537, '1f9d9':1536, '1f9da-200d-2640':1541, '1f9da-200d-2642':1540, '1f9da':1539, '1f9db-200d-2640':1544, '1f9db-200d-2642':1543, '1f9db':1542, '1f9dc-200d-2640':1547, '1f9dc-200d-2642':1546, '1f9dc':1545, '1f9dd-200d-2640':1550, '1f9dd-200d-2642':1549, '1f9dd':1548, '1f9de-200d-2640':1553, '1f9de-200d-2642':1552, '1f9de':1551, '1f9df-200d-2640':1556, '1f9df-200d-2642':1555, '1f9df':1554, '1f9e0':1376, '1f9e1':1142, '1f9e2':61148, '1f9e3':61118, '1f9e4':61119, '1f9e5':61120, '1f9e6':61121, '1f9e7':51039, '1f9e8':51028, '1f9e9':51090, '1f9ea':61320, '1f9eb':61321, '1f9ec':61322, '1f9ed':4812, '1f9ee':61201, '1f9ef':61356, '1f9f0':61316, '1f9f1':4825, '1f9f2':61317, '1f9f3':4945, '1f9f4':61346, '1f9f5':51106, '1f9f6':51108, '1f9f7':61347, '1f9f8':51091, '1f9f9':61348, '1f9fa':61349, '1f9fb':61350, '1f9fc':61352, '1f9fd':61355, '1f9fe':61243, '1f9ff':51084, '1fa70':61142, '1fa71':61125, '1fa72':61126, '1fa73':61127, '1fa74':61135, '1fa78':61327, '1fa79':61329, '1fa7a':61331, '1fa80':51079, '1fa81':51080, '1fa82':4935, '1fa83':61302, '1fa84':51083, '1fa85':51092, '1fa86':51094, '1fa90':4993, '1fa91':61339, '1fa92':61345, '1fa93':61295, '1fa94':61217, '1fa95':61179, '1fa96':61149, '1fa97':61174, '1fa98':61181, '1fa99':61236, '1fa9a':61305, '1fa9b':61307, '1fa9c':61318, '1fa9d':61315, '1fa9e':61335, '1fa9f':61336, '1faa0':61341, '1faa1':51107, '1faa2':51109, '1faa3':61351, '1faa4':61344, '1faa5':61354, '1faa6':61360, '1faa7':61363, '1faa8':4826, '1fab0':2645, '1fab1':2646, '1fab2':2637, '1fab3':2640, '1fab4':2660, '1fab5':4827, '1fab6':2608, '1fac0':1377, '1fac1':1378, '1fac2':1686, '1fad0':3688, '1fad1':3699, '1fad2':3691, '1fad3':3712, '1fad4':3729, '1fad5':3736, '1fad6':3782, '203c':62834, '21a9':62765, '21aa':62766, '231a':4948, '231b':4946, '23cf':62818, '23e9':62805, '23ea':62809, '23eb':62812, '23ec':62814, '23ed':62806, '23ee':62810, '23ef':62807, '23f0':4949, '23f1':4950, '23f2':4951, '23f3':4947, '23f8':62815, '23f9':62816, '23fa':62817, '24c2':62890, '25aa':62938, '25ab':62939, '25b6':62804, '25c0':62808, '25fb':62935, '25fc':62934, '25fd':62937, '25fe':62936, '260e':61184, '261d':1350, '262a':62784, '262e':62785, '262f':62781, '263a':120, '264a':62790, '264b':62791, '264c':62792, '264d':62793, '264e':62794, '264f':62795, '265f':51099, '267b':62844, '267e':62833, '267f':62732, '269b':62777, '269c':62845, '26a0':62742, '26a1':41016, '26a7':62827, '26aa':62924, '26ab':62923, '26b0':61359, '26b1':61361, '26bd':51051, '26be':51052, '26c4':41019, '26c5':4999, '26c8':41000, '26ce':62800, '26cf':61296, '26d1':61150, '26d3':61314, '26d4':62744, '26e9':4853, '26ea':4849, '26f0':4814, '26f1':41015, '26f2':4855, '26f3':51070, '26f4':4928, '26f5':4924, '26f7':1599, '26f8':51071, '26f9-200d-2640':1615, '26f9-200d-2642':1614, '26f9':1613, '26fa':4856, '26fd':4915, '270a':1354, '270b':1330, '270c':1339, '270d':1365, '270f':61258, '271d':62782, '274c':62853, '274e':62854, '2764-200d-1f525':1139, '2764-200d-1fa79':1140, '27a1':62757, '27b0':62855, '27bf':62856, '2b05':62761, '2b06':62755, '2b07':62759, '2b1b':62932, '2b1c':62933, '2b50':4994, '2b55':62849, '303d':62857, '1f385-1f3fb':0, '1f385-1f3fc':0, '1f385-1f3fd':0, '1f385-1f3fe':0, '1f385-1f3ff':0, '1f3c2-1f3fb':0, '1f3c2-1f3fc':0, '1f3c2-1f3fd':0, '1f3c2-1f3fe':0, '1f3c2-1f3ff':0, '1f3c3-1f3fb-200d-2640':0, '1f3c3-1f3fc-200d-2640':0, '1f3c3-1f3fd-200d-2640':0, '1f3c3-1f3fe-200d-2640':0, '1f3c3-1f3ff-200d-2640':0, '1f3c3-1f3fb-200d-2642':0, '1f3c3-1f3fc-200d-2642':0, '1f3c3-1f3fd-200d-2642':0, '1f3c3-1f3fe-200d-2642':0, '1f3c3-1f3ff-200d-2642':0, '1f3c3-1f3fb':0, '1f3c3-1f3fc':0, '1f3c3-1f3fd':0, '1f3c3-1f3fe':0, '1f3c3-1f3ff':0, '1f3c4-1f3fb-200d-2640':0, '1f3c4-1f3fc-200d-2640':0, '1f3c4-1f3fd-200d-2640':0, '1f3c4-1f3fe-200d-2640':0, '1f3c4-1f3ff-200d-2640':0, '1f3c4-1f3fb-200d-2642':0, '1f3c4-1f3fc-200d-2642':0, '1f3c4-1f3fd-200d-2642':0, '1f3c4-1f3fe-200d-2642':0, '1f3c4-1f3ff-200d-2642':0, '1f3c4-1f3fb':0, '1f3c4-1f3fc':0, '1f3c4-1f3fd':0, '1f3c4-1f3fe':0, '1f3c4-1f3ff':0, '1f3c7-1f3fb':0, '1f3c7-1f3fc':0, '1f3c7-1f3fd':0, '1f3c7-1f3fe':0, '1f3c7-1f3ff':0, '1f3ca-1f3fb-200d-2640':0, '1f3ca-1f3fc-200d-2640':0, '1f3ca-1f3fd-200d-2640':0, '1f3ca-1f3fe-200d-2640':0, '1f3ca-1f3ff-200d-2640':0, '1f3ca-1f3fb-200d-2642':0, '1f3ca-1f3fc-200d-2642':0, '1f3ca-1f3fd-200d-2642':0, '1f3ca-1f3fe-200d-2642':0, '1f3ca-1f3ff-200d-2642':0, '1f3ca-1f3fb':0, '1f3ca-1f3fc':0, '1f3ca-1f3fd':0, '1f3ca-1f3fe':0, '1f3ca-1f3ff':0, '1f3cb-1f3fb-200d-2640':0, '1f3cb-1f3fc-200d-2640':0, '1f3cb-1f3fd-200d-2640':0, '1f3cb-1f3fe-200d-2640':0, '1f3cb-1f3ff-200d-2640':0, '1f3cb-1f3fb-200d-2642':0, '1f3cb-1f3fc-200d-2642':0, '1f3cb-1f3fd-200d-2642':0, '1f3cb-1f3fe-200d-2642':0, '1f3cb-1f3ff-200d-2642':0, '1f3cb-1f3fb':0, '1f3cb-1f3fc':0, '1f3cb-1f3fd':0, '1f3cb-1f3fe':0, '1f3cb-1f3ff':0, '1f3cc-1f3fb-200d-2640':0, '1f3cc-1f3fc-200d-2640':0, '1f3cc-1f3fd-200d-2640':0, '1f3cc-1f3fe-200d-2640':0, '1f3cc-1f3ff-200d-2640':0, '1f3cc-1f3fb-200d-2642':0, '1f3cc-1f3fc-200d-2642':0, '1f3cc-1f3fd-200d-2642':0, '1f3cc-1f3fe-200d-2642':0, '1f3cc-1f3ff-200d-2642':0, '1f3cc-1f3fb':0, '1f3cc-1f3fc':0, '1f3cc-1f3fd':0, '1f3cc-1f3fe':0, '1f3cc-1f3ff':0, '1f442-1f3fb':0, '1f442-1f3fc':0, '1f442-1f3fd':0, '1f442-1f3fe':0, '1f442-1f3ff':0, '1f443-1f3fb':0, '1f443-1f3fc':0, '1f443-1f3fd':0, '1f443-1f3fe':0, '1f443-1f3ff':0, '1f446-1f3fb':0, '1f446-1f3fc':0, '1f446-1f3fd':0, '1f446-1f3fe':0, '1f446-1f3ff':0, '1f447-1f3fb':0, '1f447-1f3fc':0, '1f447-1f3fd':0, '1f447-1f3fe':0, '1f447-1f3ff':0, '1f448-1f3fb':0, '1f448-1f3fc':0, '1f448-1f3fd':0, '1f448-1f3fe':0, '1f448-1f3ff':0, '1f449-1f3fb':0, '1f449-1f3fc':0, '1f449-1f3fd':0, '1f449-1f3fe':0, '1f449-1f3ff':0, '1f44a-1f3fb':0, '1f44a-1f3fc':0, '1f44a-1f3fd':0, '1f44a-1f3fe':0, '1f44a-1f3ff':0, '1f44b-1f3fb':0, '1f44b-1f3fc':0, '1f44b-1f3fd':0, '1f44b-1f3fe':0, '1f44b-1f3ff':0, '1f44c-1f3fb':0, '1f44c-1f3fc':0, '1f44c-1f3fd':0, '1f44c-1f3fe':0, '1f44c-1f3ff':0, '1f44d-1f3fb':0, '1f44d-1f3fc':0, '1f44d-1f3fd':0, '1f44d-1f3fe':0, '1f44d-1f3ff':0, '1f44e-1f3fb':0, '1f44e-1f3fc':0, '1f44e-1f3fd':0, '1f44e-1f3fe':0, '1f44e-1f3ff':0, '1f44f-1f3fb':0, '1f44f-1f3fc':0, '1f44f-1f3fd':0, '1f44f-1f3fe':0, '1f44f-1f3ff':0, '1f450-1f3fb':0, '1f450-1f3fc':0, '1f450-1f3fd':0, '1f450-1f3fe':0, '1f450-1f3ff':0, '1f466-1f3fb':0, '1f466-1f3fc':0, '1f466-1f3fd':0, '1f466-1f3fe':0, '1f466-1f3ff':0, '1f467-1f3fb':0, '1f467-1f3fc':0, '1f467-1f3fd':0, '1f467-1f3fe':0, '1f467-1f3ff':0, '1f468-1f3fb-200d-1f33e':0, '1f468-1f3fc-200d-1f33e':0, '1f468-1f3fd-200d-1f33e':0, '1f468-1f3fe-200d-1f33e':0, '1f468-1f3ff-200d-1f33e':0, '1f468-1f3fb-200d-1f373':0, '1f468-1f3fc-200d-1f373':0, '1f468-1f3fd-200d-1f373':0, '1f468-1f3fe-200d-1f373':0, '1f468-1f3ff-200d-1f373':0, '1f468-1f3fb-200d-1f37c':0, '1f468-1f3fc-200d-1f37c':0, '1f468-1f3fd-200d-1f37c':0, '1f468-1f3fe-200d-1f37c':0, '1f468-1f3ff-200d-1f37c':0, '1f468-1f3fb-200d-1f393':0, '1f468-1f3fc-200d-1f393':0, '1f468-1f3fd-200d-1f393':0, '1f468-1f3fe-200d-1f393':0, '1f468-1f3ff-200d-1f393':0, '1f468-1f3fb-200d-1f3a4':0, '1f468-1f3fc-200d-1f3a4':0, '1f468-1f3fd-200d-1f3a4':0, '1f468-1f3fe-200d-1f3a4':0, '1f468-1f3ff-200d-1f3a4':0, '1f468-1f3fb-200d-1f3a8':0, '1f468-1f3fc-200d-1f3a8':0, '1f468-1f3fd-200d-1f3a8':0, '1f468-1f3fe-200d-1f3a8':0, '1f468-1f3ff-200d-1f3a8':0, '1f468-1f3fb-200d-1f3eb':0, '1f468-1f3fc-200d-1f3eb':0, '1f468-1f3fd-200d-1f3eb':0, '1f468-1f3fe-200d-1f3eb':0, '1f468-1f3ff-200d-1f3eb':0, '1f468-1f3fb-200d-1f3ed':0, '1f468-1f3fc-200d-1f3ed':0, '1f468-1f3fd-200d-1f3ed':0, '1f468-1f3fe-200d-1f3ed':0, '1f468-1f3ff-200d-1f3ed':0, '1f468-1f3fb-200d-1f4bb':0, '1f468-1f3fc-200d-1f4bb':0, '1f468-1f3fd-200d-1f4bb':0, '1f468-1f3fe-200d-1f4bb':0, '1f468-1f3ff-200d-1f4bb':0, '1f468-1f3fb-200d-1f4bc':0, '1f468-1f3fc-200d-1f4bc':0, '1f468-1f3fd-200d-1f4bc':0, '1f468-1f3fe-200d-1f4bc':0, '1f468-1f3ff-200d-1f4bc':0, '1f468-1f3fb-200d-1f527':0, '1f468-1f3fc-200d-1f527':0, '1f468-1f3fd-200d-1f527':0, '1f468-1f3fe-200d-1f527':0, '1f468-1f3ff-200d-1f527':0, '1f468-1f3fb-200d-1f52c':0, '1f468-1f3fc-200d-1f52c':0, '1f468-1f3fd-200d-1f52c':0, '1f468-1f3fe-200d-1f52c':0, '1f468-1f3ff-200d-1f52c':0, '1f468-1f3fb-200d-1f680':0, '1f468-1f3fc-200d-1f680':0, '1f468-1f3fd-200d-1f680':0, '1f468-1f3fe-200d-1f680':0, '1f468-1f3ff-200d-1f680':0, '1f468-1f3fb-200d-1f692':0, '1f468-1f3fc-200d-1f692':0, '1f468-1f3fd-200d-1f692':0, '1f468-1f3fe-200d-1f692':0, '1f468-1f3ff-200d-1f692':0, '1f468-1f3fb-200d-1f9af':0, '1f468-1f3fc-200d-1f9af':0, '1f468-1f3fd-200d-1f9af':0, '1f468-1f3fe-200d-1f9af':0, '1f468-1f3ff-200d-1f9af':0, '1f468-1f3fb-200d-1f9b0':0, '1f468-1f3fc-200d-1f9b0':0, '1f468-1f3fd-200d-1f9b0':0, '1f468-1f3fe-200d-1f9b0':0, '1f468-1f3ff-200d-1f9b0':0, '1f468-1f3fb-200d-1f9b1':0, '1f468-1f3fc-200d-1f9b1':0, '1f468-1f3fd-200d-1f9b1':0, '1f468-1f3fe-200d-1f9b1':0, '1f468-1f3ff-200d-1f9b1':0, '1f468-1f3fb-200d-1f9b2':0, '1f468-1f3fc-200d-1f9b2':0, '1f468-1f3fd-200d-1f9b2':0, '1f468-1f3fe-200d-1f9b2':0, '1f468-1f3ff-200d-1f9b2':0, '1f468-1f3fb-200d-1f9b3':0, '1f468-1f3fc-200d-1f9b3':0, '1f468-1f3fd-200d-1f9b3':0, '1f468-1f3fe-200d-1f9b3':0, '1f468-1f3ff-200d-1f9b3':0, '1f468-1f3fb-200d-1f9bc':0, '1f468-1f3fc-200d-1f9bc':0, '1f468-1f3fd-200d-1f9bc':0, '1f468-1f3fe-200d-1f9bc':0, '1f468-1f3ff-200d-1f9bc':0, '1f468-1f3fb-200d-1f9bd':0, '1f468-1f3fc-200d-1f9bd':0, '1f468-1f3fd-200d-1f9bd':0, '1f468-1f3fe-200d-1f9bd':0, '1f468-1f3ff-200d-1f9bd':0, '1f468-1f3fb-200d-2695':0, '1f468-1f3fc-200d-2695':0, '1f468-1f3fd-200d-2695':0, '1f468-1f3fe-200d-2695':0, '1f468-1f3ff-200d-2695':0, '1f468-1f3fb-200d-2696':0, '1f468-1f3fc-200d-2696':0, '1f468-1f3fd-200d-2696':0, '1f468-1f3fe-200d-2696':0, '1f468-1f3ff-200d-2696':0, '1f468-1f3fb-200d-2708':0, '1f468-1f3fc-200d-2708':0, '1f468-1f3fd-200d-2708':0, '1f468-1f3fe-200d-2708':0, '1f468-1f3ff-200d-2708':0, '1f468-1f3fb-200d-2764-200d-1f468-1f3fb':0, '1f468-1f3fb-200d-2764-200d-1f468-1f3fc':0, '1f468-1f3fb-200d-2764-200d-1f468-1f3fd':0, '1f468-1f3fb-200d-2764-200d-1f468-1f3fe':0, '1f468-1f3fb-200d-2764-200d-1f468-1f3ff':0, '1f468-1f3fc-200d-2764-200d-1f468-1f3fb':0, '1f468-1f3fc-200d-2764-200d-1f468-1f3fc':0, '1f468-1f3fc-200d-2764-200d-1f468-1f3fd':0, '1f468-1f3fc-200d-2764-200d-1f468-1f3fe':0, '1f468-1f3fc-200d-2764-200d-1f468-1f3ff':0, '1f468-1f3fd-200d-2764-200d-1f468-1f3fb':0, '1f468-1f3fd-200d-2764-200d-1f468-1f3fc':0, '1f468-1f3fd-200d-2764-200d-1f468-1f3fd':0, '1f468-1f3fd-200d-2764-200d-1f468-1f3fe':0, '1f468-1f3fd-200d-2764-200d-1f468-1f3ff':0, '1f468-1f3fe-200d-2764-200d-1f468-1f3fb':0, '1f468-1f3fe-200d-2764-200d-1f468-1f3fc':0, '1f468-1f3fe-200d-2764-200d-1f468-1f3fd':0, '1f468-1f3fe-200d-2764-200d-1f468-1f3fe':0, '1f468-1f3fe-200d-2764-200d-1f468-1f3ff':0, '1f468-1f3ff-200d-2764-200d-1f468-1f3fb':0, '1f468-1f3ff-200d-2764-200d-1f468-1f3fc':0, '1f468-1f3ff-200d-2764-200d-1f468-1f3fd':0, '1f468-1f3ff-200d-2764-200d-1f468-1f3fe':0, '1f468-1f3ff-200d-2764-200d-1f468-1f3ff':0, '1f468-1f3fb-200d-2764-200d-1f48b-200d-1f468-1f3fb':0, '1f468-1f3fb-200d-2764-200d-1f48b-200d-1f468-1f3fc':0, '1f468-1f3fb-200d-2764-200d-1f48b-200d-1f468-1f3fd':0, '1f468-1f3fb-200d-2764-200d-1f48b-200d-1f468-1f3fe':0, '1f468-1f3fb-200d-2764-200d-1f48b-200d-1f468-1f3ff':0, '1f468-1f3fc-200d-2764-200d-1f48b-200d-1f468-1f3fb':0, '1f468-1f3fc-200d-2764-200d-1f48b-200d-1f468-1f3fc':0, '1f468-1f3fc-200d-2764-200d-1f48b-200d-1f468-1f3fd':0, '1f468-1f3fc-200d-2764-200d-1f48b-200d-1f468-1f3fe':0, '1f468-1f3fc-200d-2764-200d-1f48b-200d-1f468-1f3ff':0, '1f468-1f3fd-200d-2764-200d-1f48b-200d-1f468-1f3fb':0, '1f468-1f3fd-200d-2764-200d-1f48b-200d-1f468-1f3fc':0, '1f468-1f3fd-200d-2764-200d-1f48b-200d-1f468-1f3fd':0, '1f468-1f3fd-200d-2764-200d-1f48b-200d-1f468-1f3fe':0, '1f468-1f3fd-200d-2764-200d-1f48b-200d-1f468-1f3ff':0, '1f468-1f3fe-200d-2764-200d-1f48b-200d-1f468-1f3fb':0, '1f468-1f3fe-200d-2764-200d-1f48b-200d-1f468-1f3fc':0, '1f468-1f3fe-200d-2764-200d-1f48b-200d-1f468-1f3fd':0, '1f468-1f3fe-200d-2764-200d-1f48b-200d-1f468-1f3fe':0, '1f468-1f3fe-200d-2764-200d-1f48b-200d-1f468-1f3ff':0, '1f468-1f3ff-200d-2764-200d-1f48b-200d-1f468-1f3fb':0, '1f468-1f3ff-200d-2764-200d-1f48b-200d-1f468-1f3fc':0, '1f468-1f3ff-200d-2764-200d-1f48b-200d-1f468-1f3fd':0, '1f468-1f3ff-200d-2764-200d-1f48b-200d-1f468-1f3fe':0, '1f468-1f3ff-200d-2764-200d-1f48b-200d-1f468-1f3ff':0, '1f468-1f3fb':0, '1f468-1f3fc':0, '1f468-1f3fd':0, '1f468-1f3fe':0, '1f468-1f3ff':0, '1f469-1f3fb-200d-1f33e':0, '1f469-1f3fc-200d-1f33e':0, '1f469-1f3fd-200d-1f33e':0, '1f469-1f3fe-200d-1f33e':0, '1f469-1f3ff-200d-1f33e':0, '1f469-1f3fb-200d-1f373':0, '1f469-1f3fc-200d-1f373':0, '1f469-1f3fd-200d-1f373':0, '1f469-1f3fe-200d-1f373':0, '1f469-1f3ff-200d-1f373':0, '1f469-1f3fb-200d-1f37c':0, '1f469-1f3fc-200d-1f37c':0, '1f469-1f3fd-200d-1f37c':0, '1f469-1f3fe-200d-1f37c':0, '1f469-1f3ff-200d-1f37c':0, '1f469-1f3fb-200d-1f393':0, '1f469-1f3fc-200d-1f393':0, '1f469-1f3fd-200d-1f393':0, '1f469-1f3fe-200d-1f393':0, '1f469-1f3ff-200d-1f393':0, '1f469-1f3fb-200d-1f3a4':0, '1f469-1f3fc-200d-1f3a4':0, '1f469-1f3fd-200d-1f3a4':0, '1f469-1f3fe-200d-1f3a4':0, '1f469-1f3ff-200d-1f3a4':0, '1f469-1f3fb-200d-1f3a8':0, '1f469-1f3fc-200d-1f3a8':0, '1f469-1f3fd-200d-1f3a8':0, '1f469-1f3fe-200d-1f3a8':0, '1f469-1f3ff-200d-1f3a8':0, '1f469-1f3fb-200d-1f3eb':0, '1f469-1f3fc-200d-1f3eb':0, '1f469-1f3fd-200d-1f3eb':0, '1f469-1f3fe-200d-1f3eb':0, '1f469-1f3ff-200d-1f3eb':0, '1f469-1f3fb-200d-1f3ed':0, '1f469-1f3fc-200d-1f3ed':0, '1f469-1f3fd-200d-1f3ed':0, '1f469-1f3fe-200d-1f3ed':0, '1f469-1f3ff-200d-1f3ed':0, '1f469-1f3fb-200d-1f4bb':0, '1f469-1f3fc-200d-1f4bb':0, '1f469-1f3fd-200d-1f4bb':0, '1f469-1f3fe-200d-1f4bb':0, '1f469-1f3ff-200d-1f4bb':0, '1f469-1f3fb-200d-1f4bc':0, '1f469-1f3fc-200d-1f4bc':0, '1f469-1f3fd-200d-1f4bc':0, '1f469-1f3fe-200d-1f4bc':0, '1f469-1f3ff-200d-1f4bc':0, '1f469-1f3fb-200d-1f527':0, '1f469-1f3fc-200d-1f527':0, '1f469-1f3fd-200d-1f527':0, '1f469-1f3fe-200d-1f527':0, '1f469-1f3ff-200d-1f527':0, '1f469-1f3fb-200d-1f52c':0, '1f469-1f3fc-200d-1f52c':0, '1f469-1f3fd-200d-1f52c':0, '1f469-1f3fe-200d-1f52c':0, '1f469-1f3ff-200d-1f52c':0, '1f469-1f3fb-200d-1f680':0, '1f469-1f3fc-200d-1f680':0, '1f469-1f3fd-200d-1f680':0, '1f469-1f3fe-200d-1f680':0, '1f469-1f3ff-200d-1f680':0, '1f469-1f3fb-200d-1f692':0, '1f469-1f3fc-200d-1f692':0, '1f469-1f3fd-200d-1f692':0, '1f469-1f3fe-200d-1f692':0, '1f469-1f3ff-200d-1f692':0, '1f469-1f3fb-200d-1f9af':0, '1f469-1f3fc-200d-1f9af':0, '1f469-1f3fd-200d-1f9af':0, '1f469-1f3fe-200d-1f9af':0, '1f469-1f3ff-200d-1f9af':0, '1f469-1f3fb-200d-1f9b0':0, '1f469-1f3fc-200d-1f9b0':0, '1f469-1f3fd-200d-1f9b0':0, '1f469-1f3fe-200d-1f9b0':0, '1f469-1f3ff-200d-1f9b0':0, '1f469-1f3fb-200d-1f9b1':0, '1f469-1f3fc-200d-1f9b1':0, '1f469-1f3fd-200d-1f9b1':0, '1f469-1f3fe-200d-1f9b1':0, '1f469-1f3ff-200d-1f9b1':0, '1f469-1f3fb-200d-1f9b2':0, '1f469-1f3fc-200d-1f9b2':0, '1f469-1f3fd-200d-1f9b2':0, '1f469-1f3fe-200d-1f9b2':0, '1f469-1f3ff-200d-1f9b2':0, '1f469-1f3fb-200d-1f9b3':0, '1f469-1f3fc-200d-1f9b3':0, '1f469-1f3fd-200d-1f9b3':0, '1f469-1f3fe-200d-1f9b3':0, '1f469-1f3ff-200d-1f9b3':0, '1f469-1f3fb-200d-1f9bc':0, '1f469-1f3fc-200d-1f9bc':0, '1f469-1f3fd-200d-1f9bc':0, '1f469-1f3fe-200d-1f9bc':0, '1f469-1f3ff-200d-1f9bc':0, '1f469-1f3fb-200d-1f9bd':0, '1f469-1f3fc-200d-1f9bd':0, '1f469-1f3fd-200d-1f9bd':0, '1f469-1f3fe-200d-1f9bd':0, '1f469-1f3ff-200d-1f9bd':0, '1f469-1f3fb-200d-2695':0, '1f469-1f3fc-200d-2695':0, '1f469-1f3fd-200d-2695':0, '1f469-1f3fe-200d-2695':0, '1f469-1f3ff-200d-2695':0, '1f469-1f3fb-200d-2696':0, '1f469-1f3fc-200d-2696':0, '1f469-1f3fd-200d-2696':0, '1f469-1f3fe-200d-2696':0, '1f469-1f3ff-200d-2696':0, '1f469-1f3fb-200d-2708':0, '1f469-1f3fc-200d-2708':0, '1f469-1f3fd-200d-2708':0, '1f469-1f3fe-200d-2708':0, '1f469-1f3ff-200d-2708':0, '1f469-1f3fb-200d-2764-200d-1f468-1f3fb':0, '1f469-1f3fb-200d-2764-200d-1f468-1f3fc':0, '1f469-1f3fb-200d-2764-200d-1f468-1f3fd':0, '1f469-1f3fb-200d-2764-200d-1f468-1f3fe':0, '1f469-1f3fb-200d-2764-200d-1f468-1f3ff':0, '1f469-1f3fc-200d-2764-200d-1f468-1f3fb':0, '1f469-1f3fc-200d-2764-200d-1f468-1f3fc':0, '1f469-1f3fc-200d-2764-200d-1f468-1f3fd':0, '1f469-1f3fc-200d-2764-200d-1f468-1f3fe':0, '1f469-1f3fc-200d-2764-200d-1f468-1f3ff':0, '1f469-1f3fd-200d-2764-200d-1f468-1f3fb':0, '1f469-1f3fd-200d-2764-200d-1f468-1f3fc':0, '1f469-1f3fd-200d-2764-200d-1f468-1f3fd':0, '1f469-1f3fd-200d-2764-200d-1f468-1f3fe':0, '1f469-1f3fd-200d-2764-200d-1f468-1f3ff':0, '1f469-1f3fe-200d-2764-200d-1f468-1f3fb':0, '1f469-1f3fe-200d-2764-200d-1f468-1f3fc':0, '1f469-1f3fe-200d-2764-200d-1f468-1f3fd':0, '1f469-1f3fe-200d-2764-200d-1f468-1f3fe':0, '1f469-1f3fe-200d-2764-200d-1f468-1f3ff':0, '1f469-1f3ff-200d-2764-200d-1f468-1f3fb':0, '1f469-1f3ff-200d-2764-200d-1f468-1f3fc':0, '1f469-1f3ff-200d-2764-200d-1f468-1f3fd':0, '1f469-1f3ff-200d-2764-200d-1f468-1f3fe':0, '1f469-1f3ff-200d-2764-200d-1f468-1f3ff':0, '1f469-1f3fb-200d-2764-200d-1f469-1f3fb':0, '1f469-1f3fb-200d-2764-200d-1f469-1f3fc':0, '1f469-1f3fb-200d-2764-200d-1f469-1f3fd':0, '1f469-1f3fb-200d-2764-200d-1f469-1f3fe':0, '1f469-1f3fb-200d-2764-200d-1f469-1f3ff':0, '1f469-1f3fc-200d-2764-200d-1f469-1f3fb':0, '1f469-1f3fc-200d-2764-200d-1f469-1f3fc':0, '1f469-1f3fc-200d-2764-200d-1f469-1f3fd':0, '1f469-1f3fc-200d-2764-200d-1f469-1f3fe':0, '1f469-1f3fc-200d-2764-200d-1f469-1f3ff':0, '1f469-1f3fd-200d-2764-200d-1f469-1f3fb':0, '1f469-1f3fd-200d-2764-200d-1f469-1f3fc':0, '1f469-1f3fd-200d-2764-200d-1f469-1f3fd':0, '1f469-1f3fd-200d-2764-200d-1f469-1f3fe':0, '1f469-1f3fd-200d-2764-200d-1f469-1f3ff':0, '1f469-1f3fe-200d-2764-200d-1f469-1f3fb':0, '1f469-1f3fe-200d-2764-200d-1f469-1f3fc':0, '1f469-1f3fe-200d-2764-200d-1f469-1f3fd':0, '1f469-1f3fe-200d-2764-200d-1f469-1f3fe':0, '1f469-1f3fe-200d-2764-200d-1f469-1f3ff':0, '1f469-1f3ff-200d-2764-200d-1f469-1f3fb':0, '1f469-1f3ff-200d-2764-200d-1f469-1f3fc':0, '1f469-1f3ff-200d-2764-200d-1f469-1f3fd':0, '1f469-1f3ff-200d-2764-200d-1f469-1f3fe':0, '1f469-1f3ff-200d-2764-200d-1f469-1f3ff':0, '1f469-1f3fb-200d-2764-200d-1f48b-200d-1f468-1f3fb':0, '1f469-1f3fb-200d-2764-200d-1f48b-200d-1f468-1f3fc':0, '1f469-1f3fb-200d-2764-200d-1f48b-200d-1f468-1f3fd':0, '1f469-1f3fb-200d-2764-200d-1f48b-200d-1f468-1f3fe':0, '1f469-1f3fb-200d-2764-200d-1f48b-200d-1f468-1f3ff':0, '1f469-1f3fc-200d-2764-200d-1f48b-200d-1f468-1f3fb':0, '1f469-1f3fc-200d-2764-200d-1f48b-200d-1f468-1f3fc':0, '1f469-1f3fc-200d-2764-200d-1f48b-200d-1f468-1f3fd':0, '1f469-1f3fc-200d-2764-200d-1f48b-200d-1f468-1f3fe':0, '1f469-1f3fc-200d-2764-200d-1f48b-200d-1f468-1f3ff':0, '1f469-1f3fd-200d-2764-200d-1f48b-200d-1f468-1f3fb':0, '1f469-1f3fd-200d-2764-200d-1f48b-200d-1f468-1f3fc':0, '1f469-1f3fd-200d-2764-200d-1f48b-200d-1f468-1f3fd':0, '1f469-1f3fd-200d-2764-200d-1f48b-200d-1f468-1f3fe':0, '1f469-1f3fd-200d-2764-200d-1f48b-200d-1f468-1f3ff':0, '1f469-1f3fe-200d-2764-200d-1f48b-200d-1f468-1f3fb':0, '1f469-1f3fe-200d-2764-200d-1f48b-200d-1f468-1f3fc':0, '1f469-1f3fe-200d-2764-200d-1f48b-200d-1f468-1f3fd':0, '1f469-1f3fe-200d-2764-200d-1f48b-200d-1f468-1f3fe':0, '1f469-1f3fe-200d-2764-200d-1f48b-200d-1f468-1f3ff':0, '1f469-1f3ff-200d-2764-200d-1f48b-200d-1f468-1f3fb':0, '1f469-1f3ff-200d-2764-200d-1f48b-200d-1f468-1f3fc':0, '1f469-1f3ff-200d-2764-200d-1f48b-200d-1f468-1f3fd':0, '1f469-1f3ff-200d-2764-200d-1f48b-200d-1f468-1f3fe':0, '1f469-1f3ff-200d-2764-200d-1f48b-200d-1f468-1f3ff':0, '1f469-1f3fb-200d-2764-200d-1f48b-200d-1f469-1f3fb':0, '1f469-1f3fb-200d-2764-200d-1f48b-200d-1f469-1f3fc':0, '1f469-1f3fb-200d-2764-200d-1f48b-200d-1f469-1f3fd':0, '1f469-1f3fb-200d-2764-200d-1f48b-200d-1f469-1f3fe':0, '1f469-1f3fb-200d-2764-200d-1f48b-200d-1f469-1f3ff':0, '1f469-1f3fc-200d-2764-200d-1f48b-200d-1f469-1f3fb':0, '1f469-1f3fc-200d-2764-200d-1f48b-200d-1f469-1f3fc':0, '1f469-1f3fc-200d-2764-200d-1f48b-200d-1f469-1f3fd':0, '1f469-1f3fc-200d-2764-200d-1f48b-200d-1f469-1f3fe':0, '1f469-1f3fc-200d-2764-200d-1f48b-200d-1f469-1f3ff':0, '1f469-1f3fd-200d-2764-200d-1f48b-200d-1f469-1f3fb':0, '1f469-1f3fd-200d-2764-200d-1f48b-200d-1f469-1f3fc':0, '1f469-1f3fd-200d-2764-200d-1f48b-200d-1f469-1f3fd':0, '1f469-1f3fd-200d-2764-200d-1f48b-200d-1f469-1f3fe':0, '1f469-1f3fd-200d-2764-200d-1f48b-200d-1f469-1f3ff':0, '1f469-1f3fe-200d-2764-200d-1f48b-200d-1f469-1f3fb':0, '1f469-1f3fe-200d-2764-200d-1f48b-200d-1f469-1f3fc':0, '1f469-1f3fe-200d-2764-200d-1f48b-200d-1f469-1f3fd':0, '1f469-1f3fe-200d-2764-200d-1f48b-200d-1f469-1f3fe':0, '1f469-1f3fe-200d-2764-200d-1f48b-200d-1f469-1f3ff':0, '1f469-1f3ff-200d-2764-200d-1f48b-200d-1f469-1f3fb':0, '1f469-1f3ff-200d-2764-200d-1f48b-200d-1f469-1f3fc':0, '1f469-1f3ff-200d-2764-200d-1f48b-200d-1f469-1f3fd':0, '1f469-1f3ff-200d-2764-200d-1f48b-200d-1f469-1f3fe':0, '1f469-1f3ff-200d-2764-200d-1f48b-200d-1f469-1f3ff':0, '1f469-1f3fb':0, '1f469-1f3fc':0, '1f469-1f3fd':0, '1f469-1f3fe':0, '1f469-1f3ff':0, '1f46b-1f3fb':0, '1f46b-1f3fc':0, '1f46b-1f3fd':0, '1f46b-1f3fe':0, '1f46b-1f3ff':0, '1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc':0, '1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd':0, '1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe':0, '1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff':0, '1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb':0, '1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd':0, '1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe':0, '1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff':0, '1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb':0, '1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc':0, '1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe':0, '1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff':0, '1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb':0, '1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc':0, '1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd':0, '1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff':0, '1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb':0, '1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc':0, '1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd':0, '1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe':0, '1f46c-1f3fb':0, '1f46c-1f3fc':0, '1f46c-1f3fd':0, '1f46c-1f3fe':0, '1f46c-1f3ff':0, '1f468-1f3fb-200d-1f91d-200d-1f468-1f3fc':0, '1f468-1f3fb-200d-1f91d-200d-1f468-1f3fd':0, '1f468-1f3fb-200d-1f91d-200d-1f468-1f3fe':0, '1f468-1f3fb-200d-1f91d-200d-1f468-1f3ff':0, '1f468-1f3fc-200d-1f91d-200d-1f468-1f3fb':0, '1f468-1f3fc-200d-1f91d-200d-1f468-1f3fd':0, '1f468-1f3fc-200d-1f91d-200d-1f468-1f3fe':0, '1f468-1f3fc-200d-1f91d-200d-1f468-1f3ff':0, '1f468-1f3fd-200d-1f91d-200d-1f468-1f3fb':0, '1f468-1f3fd-200d-1f91d-200d-1f468-1f3fc':0, '1f468-1f3fd-200d-1f91d-200d-1f468-1f3fe':0, '1f468-1f3fd-200d-1f91d-200d-1f468-1f3ff':0, '1f468-1f3fe-200d-1f91d-200d-1f468-1f3fb':0, '1f468-1f3fe-200d-1f91d-200d-1f468-1f3fc':0, '1f468-1f3fe-200d-1f91d-200d-1f468-1f3fd':0, '1f468-1f3fe-200d-1f91d-200d-1f468-1f3ff':0, '1f468-1f3ff-200d-1f91d-200d-1f468-1f3fb':0, '1f468-1f3ff-200d-1f91d-200d-1f468-1f3fc':0, '1f468-1f3ff-200d-1f91d-200d-1f468-1f3fd':0, '1f468-1f3ff-200d-1f91d-200d-1f468-1f3fe':0, '1f46d-1f3fb':0, '1f46d-1f3fc':0, '1f46d-1f3fd':0, '1f46d-1f3fe':0, '1f46d-1f3ff':0, '1f469-1f3fb-200d-1f91d-200d-1f469-1f3fc':0, '1f469-1f3fb-200d-1f91d-200d-1f469-1f3fd':0, '1f469-1f3fb-200d-1f91d-200d-1f469-1f3fe':0, '1f469-1f3fb-200d-1f91d-200d-1f469-1f3ff':0, '1f469-1f3fc-200d-1f91d-200d-1f469-1f3fb':0, '1f469-1f3fc-200d-1f91d-200d-1f469-1f3fd':0, '1f469-1f3fc-200d-1f91d-200d-1f469-1f3fe':0, '1f469-1f3fc-200d-1f91d-200d-1f469-1f3ff':0, '1f469-1f3fd-200d-1f91d-200d-1f469-1f3fb':0, '1f469-1f3fd-200d-1f91d-200d-1f469-1f3fc':0, '1f469-1f3fd-200d-1f91d-200d-1f469-1f3fe':0, '1f469-1f3fd-200d-1f91d-200d-1f469-1f3ff':0, '1f469-1f3fe-200d-1f91d-200d-1f469-1f3fb':0, '1f469-1f3fe-200d-1f91d-200d-1f469-1f3fc':0, '1f469-1f3fe-200d-1f91d-200d-1f469-1f3fd':0, '1f469-1f3fe-200d-1f91d-200d-1f469-1f3ff':0, '1f469-1f3ff-200d-1f91d-200d-1f469-1f3fb':0, '1f469-1f3ff-200d-1f91d-200d-1f469-1f3fc':0, '1f469-1f3ff-200d-1f91d-200d-1f469-1f3fd':0, '1f469-1f3ff-200d-1f91d-200d-1f469-1f3fe':0, '1f46e-1f3fb-200d-2640':0, '1f46e-1f3fc-200d-2640':0, '1f46e-1f3fd-200d-2640':0, '1f46e-1f3fe-200d-2640':0, '1f46e-1f3ff-200d-2640':0, '1f46e-1f3fb-200d-2642':0, '1f46e-1f3fc-200d-2642':0, '1f46e-1f3fd-200d-2642':0, '1f46e-1f3fe-200d-2642':0, '1f46e-1f3ff-200d-2642':0, '1f46e-1f3fb':0, '1f46e-1f3fc':0, '1f46e-1f3fd':0, '1f46e-1f3fe':0, '1f46e-1f3ff':0, '1f470-1f3fb-200d-2640':0, '1f470-1f3fc-200d-2640':0, '1f470-1f3fd-200d-2640':0, '1f470-1f3fe-200d-2640':0, '1f470-1f3ff-200d-2640':0, '1f470-1f3fb-200d-2642':0, '1f470-1f3fc-200d-2642':0, '1f470-1f3fd-200d-2642':0, '1f470-1f3fe-200d-2642':0, '1f470-1f3ff-200d-2642':0, '1f470-1f3fb':0, '1f470-1f3fc':0, '1f470-1f3fd':0, '1f470-1f3fe':0, '1f470-1f3ff':0, '1f471-1f3fb-200d-2640':0, '1f471-1f3fc-200d-2640':0, '1f471-1f3fd-200d-2640':0, '1f471-1f3fe-200d-2640':0, '1f471-1f3ff-200d-2640':0, '1f471-1f3fb-200d-2642':0, '1f471-1f3fc-200d-2642':0, '1f471-1f3fd-200d-2642':0, '1f471-1f3fe-200d-2642':0, '1f471-1f3ff-200d-2642':0, '1f471-1f3fb':0, '1f471-1f3fc':0, '1f471-1f3fd':0, '1f471-1f3fe':0, '1f471-1f3ff':0, '1f472-1f3fb':0, '1f472-1f3fc':0, '1f472-1f3fd':0, '1f472-1f3fe':0, '1f472-1f3ff':0, '1f473-1f3fb-200d-2640':0, '1f473-1f3fc-200d-2640':0, '1f473-1f3fd-200d-2640':0, '1f473-1f3fe-200d-2640':0, '1f473-1f3ff-200d-2640':0, '1f473-1f3fb-200d-2642':0, '1f473-1f3fc-200d-2642':0, '1f473-1f3fd-200d-2642':0, '1f473-1f3fe-200d-2642':0, '1f473-1f3ff-200d-2642':0, '1f473-1f3fb':0, '1f473-1f3fc':0, '1f473-1f3fd':0, '1f473-1f3fe':0, '1f473-1f3ff':0, '1f474-1f3fb':0, '1f474-1f3fc':0, '1f474-1f3fd':0, '1f474-1f3fe':0, '1f474-1f3ff':0, '1f475-1f3fb':0, '1f475-1f3fc':0, '1f475-1f3fd':0, '1f475-1f3fe':0, '1f475-1f3ff':0, '1f476-1f3fb':0, '1f476-1f3fc':0, '1f476-1f3fd':0, '1f476-1f3fe':0, '1f476-1f3ff':0, '1f477-1f3fb-200d-2640':0, '1f477-1f3fc-200d-2640':0, '1f477-1f3fd-200d-2640':0, '1f477-1f3fe-200d-2640':0, '1f477-1f3ff-200d-2640':0, '1f477-1f3fb-200d-2642':0, '1f477-1f3fc-200d-2642':0, '1f477-1f3fd-200d-2642':0, '1f477-1f3fe-200d-2642':0, '1f477-1f3ff-200d-2642':0, '1f477-1f3fb':0, '1f477-1f3fc':0, '1f477-1f3fd':0, '1f477-1f3fe':0, '1f477-1f3ff':0, '1f478-1f3fb':0, '1f478-1f3fc':0, '1f478-1f3fd':0, '1f478-1f3fe':0, '1f478-1f3ff':0, '1f47c-1f3fb':0, '1f47c-1f3fc':0, '1f47c-1f3fd':0, '1f47c-1f3fe':0, '1f47c-1f3ff':0, '1f481-1f3fb-200d-2640':0, '1f481-1f3fc-200d-2640':0, '1f481-1f3fd-200d-2640':0, '1f481-1f3fe-200d-2640':0, '1f481-1f3ff-200d-2640':0, '1f481-1f3fb-200d-2642':0, '1f481-1f3fc-200d-2642':0, '1f481-1f3fd-200d-2642':0, '1f481-1f3fe-200d-2642':0, '1f481-1f3ff-200d-2642':0, '1f481-1f3fb':0, '1f481-1f3fc':0, '1f481-1f3fd':0, '1f481-1f3fe':0, '1f481-1f3ff':0, '1f482-1f3fb-200d-2640':0, '1f482-1f3fc-200d-2640':0, '1f482-1f3fd-200d-2640':0, '1f482-1f3fe-200d-2640':0, '1f482-1f3ff-200d-2640':0, '1f482-1f3fb-200d-2642':0, '1f482-1f3fc-200d-2642':0, '1f482-1f3fd-200d-2642':0, '1f482-1f3fe-200d-2642':0, '1f482-1f3ff-200d-2642':0, '1f482-1f3fb':0, '1f482-1f3fc':0, '1f482-1f3fd':0, '1f482-1f3fe':0, '1f482-1f3ff':0, '1f483-1f3fb':0, '1f483-1f3fc':0, '1f483-1f3fd':0, '1f483-1f3fe':0, '1f483-1f3ff':0, '1f485-1f3fb':0, '1f485-1f3fc':0, '1f485-1f3fd':0, '1f485-1f3fe':0, '1f485-1f3ff':0, '1f486-1f3fb-200d-2640':0, '1f486-1f3fc-200d-2640':0, '1f486-1f3fd-200d-2640':0, '1f486-1f3fe-200d-2640':0, '1f486-1f3ff-200d-2640':0, '1f486-1f3fb-200d-2642':0, '1f486-1f3fc-200d-2642':0, '1f486-1f3fd-200d-2642':0, '1f486-1f3fe-200d-2642':0, '1f486-1f3ff-200d-2642':0, '1f486-1f3fb':0, '1f486-1f3fc':0, '1f486-1f3fd':0, '1f486-1f3fe':0, '1f486-1f3ff':0, '1f487-1f3fb-200d-2640':0, '1f487-1f3fc-200d-2640':0, '1f487-1f3fd-200d-2640':0, '1f487-1f3fe-200d-2640':0, '1f487-1f3ff-200d-2640':0, '1f487-1f3fb-200d-2642':0, '1f487-1f3fc-200d-2642':0, '1f487-1f3fd-200d-2642':0, '1f487-1f3fe-200d-2642':0, '1f487-1f3ff-200d-2642':0, '1f487-1f3fb':0, '1f487-1f3fc':0, '1f487-1f3fd':0, '1f487-1f3fe':0, '1f487-1f3ff':0, '1f48f-1f3fb':0, '1f48f-1f3fc':0, '1f48f-1f3fd':0, '1f48f-1f3fe':0, '1f48f-1f3ff':0, '1f9d1-1f3fb-200d-2764-200d-1f48b-200d-1f9d1-1f3fc':0, '1f9d1-1f3fb-200d-2764-200d-1f48b-200d-1f9d1-1f3fd':0, '1f9d1-1f3fb-200d-2764-200d-1f48b-200d-1f9d1-1f3fe':0, '1f9d1-1f3fb-200d-2764-200d-1f48b-200d-1f9d1-1f3ff':0, '1f9d1-1f3fc-200d-2764-200d-1f48b-200d-1f9d1-1f3fb':0, '1f9d1-1f3fc-200d-2764-200d-1f48b-200d-1f9d1-1f3fd':0, '1f9d1-1f3fc-200d-2764-200d-1f48b-200d-1f9d1-1f3fe':0, '1f9d1-1f3fc-200d-2764-200d-1f48b-200d-1f9d1-1f3ff':0, '1f9d1-1f3fd-200d-2764-200d-1f48b-200d-1f9d1-1f3fb':0, '1f9d1-1f3fd-200d-2764-200d-1f48b-200d-1f9d1-1f3fc':0, '1f9d1-1f3fd-200d-2764-200d-1f48b-200d-1f9d1-1f3fe':0, '1f9d1-1f3fd-200d-2764-200d-1f48b-200d-1f9d1-1f3ff':0, '1f9d1-1f3fe-200d-2764-200d-1f48b-200d-1f9d1-1f3fb':0, '1f9d1-1f3fe-200d-2764-200d-1f48b-200d-1f9d1-1f3fc':0, '1f9d1-1f3fe-200d-2764-200d-1f48b-200d-1f9d1-1f3fd':0, '1f9d1-1f3fe-200d-2764-200d-1f48b-200d-1f9d1-1f3ff':0, '1f9d1-1f3ff-200d-2764-200d-1f48b-200d-1f9d1-1f3fb':0, '1f9d1-1f3ff-200d-2764-200d-1f48b-200d-1f9d1-1f3fc':0, '1f9d1-1f3ff-200d-2764-200d-1f48b-200d-1f9d1-1f3fd':0, '1f9d1-1f3ff-200d-2764-200d-1f48b-200d-1f9d1-1f3fe':0, '1f491-1f3fb':0, '1f491-1f3fc':0, '1f491-1f3fd':0, '1f491-1f3fe':0, '1f491-1f3ff':0, '1f9d1-1f3fb-200d-2764-200d-1f9d1-1f3fc':0, '1f9d1-1f3fb-200d-2764-200d-1f9d1-1f3fd':0, '1f9d1-1f3fb-200d-2764-200d-1f9d1-1f3fe':0, '1f9d1-1f3fb-200d-2764-200d-1f9d1-1f3ff':0, '1f9d1-1f3fc-200d-2764-200d-1f9d1-1f3fb':0, '1f9d1-1f3fc-200d-2764-200d-1f9d1-1f3fd':0, '1f9d1-1f3fc-200d-2764-200d-1f9d1-1f3fe':0, '1f9d1-1f3fc-200d-2764-200d-1f9d1-1f3ff':0, '1f9d1-1f3fd-200d-2764-200d-1f9d1-1f3fb':0, '1f9d1-1f3fd-200d-2764-200d-1f9d1-1f3fc':0, '1f9d1-1f3fd-200d-2764-200d-1f9d1-1f3fe':0, '1f9d1-1f3fd-200d-2764-200d-1f9d1-1f3ff':0, '1f9d1-1f3fe-200d-2764-200d-1f9d1-1f3fb':0, '1f9d1-1f3fe-200d-2764-200d-1f9d1-1f3fc':0, '1f9d1-1f3fe-200d-2764-200d-1f9d1-1f3fd':0, '1f9d1-1f3fe-200d-2764-200d-1f9d1-1f3ff':0, '1f9d1-1f3ff-200d-2764-200d-1f9d1-1f3fb':0, '1f9d1-1f3ff-200d-2764-200d-1f9d1-1f3fc':0, '1f9d1-1f3ff-200d-2764-200d-1f9d1-1f3fd':0, '1f9d1-1f3ff-200d-2764-200d-1f9d1-1f3fe':0, '1f4aa-1f3fb':0, '1f4aa-1f3fc':0, '1f4aa-1f3fd':0, '1f4aa-1f3fe':0, '1f4aa-1f3ff':0, '1f574-1f3fb':0, '1f574-1f3fc':0, '1f574-1f3fd':0, '1f574-1f3fe':0, '1f574-1f3ff':0, '1f575-1f3fb-200d-2640':0, '1f575-1f3fc-200d-2640':0, '1f575-1f3fd-200d-2640':0, '1f575-1f3fe-200d-2640':0, '1f575-1f3ff-200d-2640':0, '1f575-1f3fb-200d-2642':0, '1f575-1f3fc-200d-2642':0, '1f575-1f3fd-200d-2642':0, '1f575-1f3fe-200d-2642':0, '1f575-1f3ff-200d-2642':0, '1f575-1f3fb':0, '1f575-1f3fc':0, '1f575-1f3fd':0, '1f575-1f3fe':0, '1f575-1f3ff':0, '1f57a-1f3fb':0, '1f57a-1f3fc':0, '1f57a-1f3fd':0, '1f57a-1f3fe':0, '1f57a-1f3ff':0, '1f590-1f3fb':0, '1f590-1f3fc':0, '1f590-1f3fd':0, '1f590-1f3fe':0, '1f590-1f3ff':0, '1f595-1f3fb':0, '1f595-1f3fc':0, '1f595-1f3fd':0, '1f595-1f3fe':0, '1f595-1f3ff':0, '1f596-1f3fb':0, '1f596-1f3fc':0, '1f596-1f3fd':0, '1f596-1f3fe':0, '1f596-1f3ff':0, '1f645-1f3fb-200d-2640':0, '1f645-1f3fc-200d-2640':0, '1f645-1f3fd-200d-2640':0, '1f645-1f3fe-200d-2640':0, '1f645-1f3ff-200d-2640':0, '1f645-1f3fb-200d-2642':0, '1f645-1f3fc-200d-2642':0, '1f645-1f3fd-200d-2642':0, '1f645-1f3fe-200d-2642':0, '1f645-1f3ff-200d-2642':0, '1f645-1f3fb':0, '1f645-1f3fc':0, '1f645-1f3fd':0, '1f645-1f3fe':0, '1f645-1f3ff':0, '1f646-1f3fb-200d-2640':0, '1f646-1f3fc-200d-2640':0, '1f646-1f3fd-200d-2640':0, '1f646-1f3fe-200d-2640':0, '1f646-1f3ff-200d-2640':0, '1f646-1f3fb-200d-2642':0, '1f646-1f3fc-200d-2642':0, '1f646-1f3fd-200d-2642':0, '1f646-1f3fe-200d-2642':0, '1f646-1f3ff-200d-2642':0, '1f646-1f3fb':0, '1f646-1f3fc':0, '1f646-1f3fd':0, '1f646-1f3fe':0, '1f646-1f3ff':0, '1f647-1f3fb-200d-2640':0, '1f647-1f3fc-200d-2640':0, '1f647-1f3fd-200d-2640':0, '1f647-1f3fe-200d-2640':0, '1f647-1f3ff-200d-2640':0, '1f647-1f3fb-200d-2642':0, '1f647-1f3fc-200d-2642':0, '1f647-1f3fd-200d-2642':0, '1f647-1f3fe-200d-2642':0, '1f647-1f3ff-200d-2642':0, '1f647-1f3fb':0, '1f647-1f3fc':0, '1f647-1f3fd':0, '1f647-1f3fe':0, '1f647-1f3ff':0, '1f64b-1f3fb-200d-2640':0, '1f64b-1f3fc-200d-2640':0, '1f64b-1f3fd-200d-2640':0, '1f64b-1f3fe-200d-2640':0, '1f64b-1f3ff-200d-2640':0, '1f64b-1f3fb-200d-2642':0, '1f64b-1f3fc-200d-2642':0, '1f64b-1f3fd-200d-2642':0, '1f64b-1f3fe-200d-2642':0, '1f64b-1f3ff-200d-2642':0, '1f64b-1f3fb':0, '1f64b-1f3fc':0, '1f64b-1f3fd':0, '1f64b-1f3fe':0, '1f64b-1f3ff':0, '1f64c-1f3fb':0, '1f64c-1f3fc':0, '1f64c-1f3fd':0, '1f64c-1f3fe':0, '1f64c-1f3ff':0, '1f64d-1f3fb-200d-2640':0, '1f64d-1f3fc-200d-2640':0, '1f64d-1f3fd-200d-2640':0, '1f64d-1f3fe-200d-2640':0, '1f64d-1f3ff-200d-2640':0, '1f64d-1f3fb-200d-2642':0, '1f64d-1f3fc-200d-2642':0, '1f64d-1f3fd-200d-2642':0, '1f64d-1f3fe-200d-2642':0, '1f64d-1f3ff-200d-2642':0, '1f64d-1f3fb':0, '1f64d-1f3fc':0, '1f64d-1f3fd':0, '1f64d-1f3fe':0, '1f64d-1f3ff':0, '1f64e-1f3fb-200d-2640':0, '1f64e-1f3fc-200d-2640':0, '1f64e-1f3fd-200d-2640':0, '1f64e-1f3fe-200d-2640':0, '1f64e-1f3ff-200d-2640':0, '1f64e-1f3fb-200d-2642':0, '1f64e-1f3fc-200d-2642':0, '1f64e-1f3fd-200d-2642':0, '1f64e-1f3fe-200d-2642':0, '1f64e-1f3ff-200d-2642':0, '1f64e-1f3fb':0, '1f64e-1f3fc':0, '1f64e-1f3fd':0, '1f64e-1f3fe':0, '1f64e-1f3ff':0, '1f64f-1f3fb':0, '1f64f-1f3fc':0, '1f64f-1f3fd':0, '1f64f-1f3fe':0, '1f64f-1f3ff':0, '1f6a3-1f3fb-200d-2640':0, '1f6a3-1f3fc-200d-2640':0, '1f6a3-1f3fd-200d-2640':0, '1f6a3-1f3fe-200d-2640':0, '1f6a3-1f3ff-200d-2640':0, '1f6a3-1f3fb-200d-2642':0, '1f6a3-1f3fc-200d-2642':0, '1f6a3-1f3fd-200d-2642':0, '1f6a3-1f3fe-200d-2642':0, '1f6a3-1f3ff-200d-2642':0, '1f6a3-1f3fb':0, '1f6a3-1f3fc':0, '1f6a3-1f3fd':0, '1f6a3-1f3fe':0, '1f6a3-1f3ff':0, '1f6b4-1f3fb-200d-2640':0, '1f6b4-1f3fc-200d-2640':0, '1f6b4-1f3fd-200d-2640':0, '1f6b4-1f3fe-200d-2640':0, '1f6b4-1f3ff-200d-2640':0, '1f6b4-1f3fb-200d-2642':0, '1f6b4-1f3fc-200d-2642':0, '1f6b4-1f3fd-200d-2642':0, '1f6b4-1f3fe-200d-2642':0, '1f6b4-1f3ff-200d-2642':0, '1f6b4-1f3fb':0, '1f6b4-1f3fc':0, '1f6b4-1f3fd':0, '1f6b4-1f3fe':0, '1f6b4-1f3ff':0, '1f6b5-1f3fb-200d-2640':0, '1f6b5-1f3fc-200d-2640':0, '1f6b5-1f3fd-200d-2640':0, '1f6b5-1f3fe-200d-2640':0, '1f6b5-1f3ff-200d-2640':0, '1f6b5-1f3fb-200d-2642':0, '1f6b5-1f3fc-200d-2642':0, '1f6b5-1f3fd-200d-2642':0, '1f6b5-1f3fe-200d-2642':0, '1f6b5-1f3ff-200d-2642':0, '1f6b5-1f3fb':0, '1f6b5-1f3fc':0, '1f6b5-1f3fd':0, '1f6b5-1f3fe':0, '1f6b5-1f3ff':0, '1f6b6-1f3fb-200d-2640':0, '1f6b6-1f3fc-200d-2640':0, '1f6b6-1f3fd-200d-2640':0, '1f6b6-1f3fe-200d-2640':0, '1f6b6-1f3ff-200d-2640':0, '1f6b6-1f3fb-200d-2642':0, '1f6b6-1f3fc-200d-2642':0, '1f6b6-1f3fd-200d-2642':0, '1f6b6-1f3fe-200d-2642':0, '1f6b6-1f3ff-200d-2642':0, '1f6b6-1f3fb':0, '1f6b6-1f3fc':0, '1f6b6-1f3fd':0, '1f6b6-1f3fe':0, '1f6b6-1f3ff':0, '1f6c0-1f3fb':0, '1f6c0-1f3fc':0, '1f6c0-1f3fd':0, '1f6c0-1f3fe':0, '1f6c0-1f3ff':0, '1f6cc-1f3fb':0, '1f6cc-1f3fc':0, '1f6cc-1f3fd':0, '1f6cc-1f3fe':0, '1f6cc-1f3ff':0, '1f90c-1f3fb':0, '1f90c-1f3fc':0, '1f90c-1f3fd':0, '1f90c-1f3fe':0, '1f90c-1f3ff':0, '1f90f-1f3fb':0, '1f90f-1f3fc':0, '1f90f-1f3fd':0, '1f90f-1f3fe':0, '1f90f-1f3ff':0, '1f918-1f3fb':0, '1f918-1f3fc':0, '1f918-1f3fd':0, '1f918-1f3fe':0, '1f918-1f3ff':0, '1f919-1f3fb':0, '1f919-1f3fc':0, '1f919-1f3fd':0, '1f919-1f3fe':0, '1f919-1f3ff':0, '1f91a-1f3fb':0, '1f91a-1f3fc':0, '1f91a-1f3fd':0, '1f91a-1f3fe':0, '1f91a-1f3ff':0, '1f91b-1f3fb':0, '1f91b-1f3fc':0, '1f91b-1f3fd':0, '1f91b-1f3fe':0, '1f91b-1f3ff':0, '1f91c-1f3fb':0, '1f91c-1f3fc':0, '1f91c-1f3fd':0, '1f91c-1f3fe':0, '1f91c-1f3ff':0, '1f91d-1f3fb':0, '1f91d-1f3fc':0, '1f91d-1f3fd':0, '1f91d-1f3fe':0, '1f91d-1f3ff':0, '1f91e-1f3fb':0, '1f91e-1f3fc':0, '1f91e-1f3fd':0, '1f91e-1f3fe':0, '1f91e-1f3ff':0, '1f91f-1f3fb':0, '1f91f-1f3fc':0, '1f91f-1f3fd':0, '1f91f-1f3fe':0, '1f91f-1f3ff':0, '1f926-1f3fb-200d-2640':0, '1f926-1f3fc-200d-2640':0, '1f926-1f3fd-200d-2640':0, '1f926-1f3fe-200d-2640':0, '1f926-1f3ff-200d-2640':0, '1f926-1f3fb-200d-2642':0, '1f926-1f3fc-200d-2642':0, '1f926-1f3fd-200d-2642':0, '1f926-1f3fe-200d-2642':0, '1f926-1f3ff-200d-2642':0, '1f926-1f3fb':0, '1f926-1f3fc':0, '1f926-1f3fd':0, '1f926-1f3fe':0, '1f926-1f3ff':0, '1f930-1f3fb':0, '1f930-1f3fc':0, '1f930-1f3fd':0, '1f930-1f3fe':0, '1f930-1f3ff':0, '1f931-1f3fb':0, '1f931-1f3fc':0, '1f931-1f3fd':0, '1f931-1f3fe':0, '1f931-1f3ff':0, '1f932-1f3fb':0, '1f932-1f3fc':0, '1f932-1f3fd':0, '1f932-1f3fe':0, '1f932-1f3ff':0, '1f933-1f3fb':0, '1f933-1f3fc':0, '1f933-1f3fd':0, '1f933-1f3fe':0, '1f933-1f3ff':0, '1f934-1f3fb':0, '1f934-1f3fc':0, '1f934-1f3fd':0, '1f934-1f3fe':0, '1f934-1f3ff':0, '1f935-1f3fb-200d-2640':0, '1f935-1f3fc-200d-2640':0, '1f935-1f3fd-200d-2640':0, '1f935-1f3fe-200d-2640':0, '1f935-1f3ff-200d-2640':0, '1f935-1f3fb-200d-2642':0, '1f935-1f3fc-200d-2642':0, '1f935-1f3fd-200d-2642':0, '1f935-1f3fe-200d-2642':0, '1f935-1f3ff-200d-2642':0, '1f935-1f3fb':0, '1f935-1f3fc':0, '1f935-1f3fd':0, '1f935-1f3fe':0, '1f935-1f3ff':0, '1f936-1f3fb':0, '1f936-1f3fc':0, '1f936-1f3fd':0, '1f936-1f3fe':0, '1f936-1f3ff':0, '1f937-1f3fb-200d-2640':0, '1f937-1f3fc-200d-2640':0, '1f937-1f3fd-200d-2640':0, '1f937-1f3fe-200d-2640':0, '1f937-1f3ff-200d-2640':0, '1f937-1f3fb-200d-2642':0, '1f937-1f3fc-200d-2642':0, '1f937-1f3fd-200d-2642':0, '1f937-1f3fe-200d-2642':0, '1f937-1f3ff-200d-2642':0, '1f937-1f3fb':0, '1f937-1f3fc':0, '1f937-1f3fd':0, '1f937-1f3fe':0, '1f937-1f3ff':0, '1f938-1f3fb-200d-2640':0, '1f938-1f3fc-200d-2640':0, '1f938-1f3fd-200d-2640':0, '1f938-1f3fe-200d-2640':0, '1f938-1f3ff-200d-2640':0, '1f938-1f3fb-200d-2642':0, '1f938-1f3fc-200d-2642':0, '1f938-1f3fd-200d-2642':0, '1f938-1f3fe-200d-2642':0, '1f938-1f3ff-200d-2642':0, '1f938-1f3fb':0, '1f938-1f3fc':0, '1f938-1f3fd':0, '1f938-1f3fe':0, '1f938-1f3ff':0, '1f939-1f3fb-200d-2640':0, '1f939-1f3fc-200d-2640':0, '1f939-1f3fd-200d-2640':0, '1f939-1f3fe-200d-2640':0, '1f939-1f3ff-200d-2640':0, '1f939-1f3fb-200d-2642':0, '1f939-1f3fc-200d-2642':0, '1f939-1f3fd-200d-2642':0, '1f939-1f3fe-200d-2642':0, '1f939-1f3ff-200d-2642':0, '1f939-1f3fb':0, '1f939-1f3fc':0, '1f939-1f3fd':0, '1f939-1f3fe':0, '1f939-1f3ff':0, '1f93d-1f3fb-200d-2640':0, '1f93d-1f3fc-200d-2640':0, '1f93d-1f3fd-200d-2640':0, '1f93d-1f3fe-200d-2640':0, '1f93d-1f3ff-200d-2640':0, '1f93d-1f3fb-200d-2642':0, '1f93d-1f3fc-200d-2642':0, '1f93d-1f3fd-200d-2642':0, '1f93d-1f3fe-200d-2642':0, '1f93d-1f3ff-200d-2642':0, '1f93d-1f3fb':0, '1f93d-1f3fc':0, '1f93d-1f3fd':0, '1f93d-1f3fe':0, '1f93d-1f3ff':0, '1f93e-1f3fb-200d-2640':0, '1f93e-1f3fc-200d-2640':0, '1f93e-1f3fd-200d-2640':0, '1f93e-1f3fe-200d-2640':0, '1f93e-1f3ff-200d-2640':0, '1f93e-1f3fb-200d-2642':0, '1f93e-1f3fc-200d-2642':0, '1f93e-1f3fd-200d-2642':0, '1f93e-1f3fe-200d-2642':0, '1f93e-1f3ff-200d-2642':0, '1f93e-1f3fb':0, '1f93e-1f3fc':0, '1f93e-1f3fd':0, '1f93e-1f3fe':0, '1f93e-1f3ff':0, '1f977-1f3fb':0, '1f977-1f3fc':0, '1f977-1f3fd':0, '1f977-1f3fe':0, '1f977-1f3ff':0, '1f9b5-1f3fb':0, '1f9b5-1f3fc':0, '1f9b5-1f3fd':0, '1f9b5-1f3fe':0, '1f9b5-1f3ff':0, '1f9b6-1f3fb':0, '1f9b6-1f3fc':0, '1f9b6-1f3fd':0, '1f9b6-1f3fe':0, '1f9b6-1f3ff':0, '1f9b8-1f3fb-200d-2640':0, '1f9b8-1f3fc-200d-2640':0, '1f9b8-1f3fd-200d-2640':0, '1f9b8-1f3fe-200d-2640':0, '1f9b8-1f3ff-200d-2640':0, '1f9b8-1f3fb-200d-2642':0, '1f9b8-1f3fc-200d-2642':0, '1f9b8-1f3fd-200d-2642':0, '1f9b8-1f3fe-200d-2642':0, '1f9b8-1f3ff-200d-2642':0, '1f9b8-1f3fb':0, '1f9b8-1f3fc':0, '1f9b8-1f3fd':0, '1f9b8-1f3fe':0, '1f9b8-1f3ff':0, '1f9b9-1f3fb-200d-2640':0, '1f9b9-1f3fc-200d-2640':0, '1f9b9-1f3fd-200d-2640':0, '1f9b9-1f3fe-200d-2640':0, '1f9b9-1f3ff-200d-2640':0, '1f9b9-1f3fb-200d-2642':0, '1f9b9-1f3fc-200d-2642':0, '1f9b9-1f3fd-200d-2642':0, '1f9b9-1f3fe-200d-2642':0, '1f9b9-1f3ff-200d-2642':0, '1f9b9-1f3fb':0, '1f9b9-1f3fc':0, '1f9b9-1f3fd':0, '1f9b9-1f3fe':0, '1f9b9-1f3ff':0, '1f9bb-1f3fb':0, '1f9bb-1f3fc':0, '1f9bb-1f3fd':0, '1f9bb-1f3fe':0, '1f9bb-1f3ff':0, '1f9cd-1f3fb-200d-2640':0, '1f9cd-1f3fc-200d-2640':0, '1f9cd-1f3fd-200d-2640':0, '1f9cd-1f3fe-200d-2640':0, '1f9cd-1f3ff-200d-2640':0, '1f9cd-1f3fb-200d-2642':0, '1f9cd-1f3fc-200d-2642':0, '1f9cd-1f3fd-200d-2642':0, '1f9cd-1f3fe-200d-2642':0, '1f9cd-1f3ff-200d-2642':0, '1f9cd-1f3fb':0, '1f9cd-1f3fc':0, '1f9cd-1f3fd':0, '1f9cd-1f3fe':0, '1f9cd-1f3ff':0, '1f9ce-1f3fb-200d-2640':0, '1f9ce-1f3fc-200d-2640':0, '1f9ce-1f3fd-200d-2640':0, '1f9ce-1f3fe-200d-2640':0, '1f9ce-1f3ff-200d-2640':0, '1f9ce-1f3fb-200d-2642':0, '1f9ce-1f3fc-200d-2642':0, '1f9ce-1f3fd-200d-2642':0, '1f9ce-1f3fe-200d-2642':0, '1f9ce-1f3ff-200d-2642':0, '1f9ce-1f3fb':0, '1f9ce-1f3fc':0, '1f9ce-1f3fd':0, '1f9ce-1f3fe':0, '1f9ce-1f3ff':0, '1f9cf-1f3fb-200d-2640':0, '1f9cf-1f3fc-200d-2640':0, '1f9cf-1f3fd-200d-2640':0, '1f9cf-1f3fe-200d-2640':0, '1f9cf-1f3ff-200d-2640':0, '1f9cf-1f3fb-200d-2642':0, '1f9cf-1f3fc-200d-2642':0, '1f9cf-1f3fd-200d-2642':0, '1f9cf-1f3fe-200d-2642':0, '1f9cf-1f3ff-200d-2642':0, '1f9cf-1f3fb':0, '1f9cf-1f3fc':0, '1f9cf-1f3fd':0, '1f9cf-1f3fe':0, '1f9cf-1f3ff':0, '1f9d1-1f3fb-200d-1f33e':0, '1f9d1-1f3fc-200d-1f33e':0, '1f9d1-1f3fd-200d-1f33e':0, '1f9d1-1f3fe-200d-1f33e':0, '1f9d1-1f3ff-200d-1f33e':0, '1f9d1-1f3fb-200d-1f373':0, '1f9d1-1f3fc-200d-1f373':0, '1f9d1-1f3fd-200d-1f373':0, '1f9d1-1f3fe-200d-1f373':0, '1f9d1-1f3ff-200d-1f373':0, '1f9d1-1f3fb-200d-1f37c':0, '1f9d1-1f3fc-200d-1f37c':0, '1f9d1-1f3fd-200d-1f37c':0, '1f9d1-1f3fe-200d-1f37c':0, '1f9d1-1f3ff-200d-1f37c':0, '1f9d1-1f3fb-200d-1f384':0, '1f9d1-1f3fc-200d-1f384':0, '1f9d1-1f3fd-200d-1f384':0, '1f9d1-1f3fe-200d-1f384':0, '1f9d1-1f3ff-200d-1f384':0, '1f9d1-1f3fb-200d-1f393':0, '1f9d1-1f3fc-200d-1f393':0, '1f9d1-1f3fd-200d-1f393':0, '1f9d1-1f3fe-200d-1f393':0, '1f9d1-1f3ff-200d-1f393':0, '1f9d1-1f3fb-200d-1f3a4':0, '1f9d1-1f3fc-200d-1f3a4':0, '1f9d1-1f3fd-200d-1f3a4':0, '1f9d1-1f3fe-200d-1f3a4':0, '1f9d1-1f3ff-200d-1f3a4':0, '1f9d1-1f3fb-200d-1f3a8':0, '1f9d1-1f3fc-200d-1f3a8':0, '1f9d1-1f3fd-200d-1f3a8':0, '1f9d1-1f3fe-200d-1f3a8':0, '1f9d1-1f3ff-200d-1f3a8':0, '1f9d1-1f3fb-200d-1f3eb':0, '1f9d1-1f3fc-200d-1f3eb':0, '1f9d1-1f3fd-200d-1f3eb':0, '1f9d1-1f3fe-200d-1f3eb':0, '1f9d1-1f3ff-200d-1f3eb':0, '1f9d1-1f3fb-200d-1f3ed':0, '1f9d1-1f3fc-200d-1f3ed':0, '1f9d1-1f3fd-200d-1f3ed':0, '1f9d1-1f3fe-200d-1f3ed':0, '1f9d1-1f3ff-200d-1f3ed':0, '1f9d1-1f3fb-200d-1f4bb':0, '1f9d1-1f3fc-200d-1f4bb':0, '1f9d1-1f3fd-200d-1f4bb':0, '1f9d1-1f3fe-200d-1f4bb':0, '1f9d1-1f3ff-200d-1f4bb':0, '1f9d1-1f3fb-200d-1f4bc':0, '1f9d1-1f3fc-200d-1f4bc':0, '1f9d1-1f3fd-200d-1f4bc':0, '1f9d1-1f3fe-200d-1f4bc':0, '1f9d1-1f3ff-200d-1f4bc':0, '1f9d1-1f3fb-200d-1f527':0, '1f9d1-1f3fc-200d-1f527':0, '1f9d1-1f3fd-200d-1f527':0, '1f9d1-1f3fe-200d-1f527':0, '1f9d1-1f3ff-200d-1f527':0, '1f9d1-1f3fb-200d-1f52c':0, '1f9d1-1f3fc-200d-1f52c':0, '1f9d1-1f3fd-200d-1f52c':0, '1f9d1-1f3fe-200d-1f52c':0, '1f9d1-1f3ff-200d-1f52c':0, '1f9d1-1f3fb-200d-1f680':0, '1f9d1-1f3fc-200d-1f680':0, '1f9d1-1f3fd-200d-1f680':0, '1f9d1-1f3fe-200d-1f680':0, '1f9d1-1f3ff-200d-1f680':0, '1f9d1-1f3fb-200d-1f692':0, '1f9d1-1f3fc-200d-1f692':0, '1f9d1-1f3fd-200d-1f692':0, '1f9d1-1f3fe-200d-1f692':0, '1f9d1-1f3ff-200d-1f692':0, '1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fb':0, '1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fc':0, '1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fd':0, '1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fe':0, '1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3ff':0, '1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fb':0, '1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fc':0, '1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fd':0, '1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fe':0, '1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3ff':0, '1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fb':0, '1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fc':0, '1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fd':0, '1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fe':0, '1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3ff':0, '1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fb':0, '1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fc':0, '1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fd':0, '1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fe':0, '1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3ff':0, '1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fb':0, '1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fc':0, '1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fd':0, '1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fe':0, '1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3ff':0, '1f9d1-1f3fb-200d-1f9af':0, '1f9d1-1f3fc-200d-1f9af':0, '1f9d1-1f3fd-200d-1f9af':0, '1f9d1-1f3fe-200d-1f9af':0, '1f9d1-1f3ff-200d-1f9af':0, '1f9d1-1f3fb-200d-1f9b0':0, '1f9d1-1f3fc-200d-1f9b0':0, '1f9d1-1f3fd-200d-1f9b0':0, '1f9d1-1f3fe-200d-1f9b0':0, '1f9d1-1f3ff-200d-1f9b0':0, '1f9d1-1f3fb-200d-1f9b1':0, '1f9d1-1f3fc-200d-1f9b1':0, '1f9d1-1f3fd-200d-1f9b1':0, '1f9d1-1f3fe-200d-1f9b1':0, '1f9d1-1f3ff-200d-1f9b1':0, '1f9d1-1f3fb-200d-1f9b2':0, '1f9d1-1f3fc-200d-1f9b2':0, '1f9d1-1f3fd-200d-1f9b2':0, '1f9d1-1f3fe-200d-1f9b2':0, '1f9d1-1f3ff-200d-1f9b2':0, '1f9d1-1f3fb-200d-1f9b3':0, '1f9d1-1f3fc-200d-1f9b3':0, '1f9d1-1f3fd-200d-1f9b3':0, '1f9d1-1f3fe-200d-1f9b3':0, '1f9d1-1f3ff-200d-1f9b3':0, '1f9d1-1f3fb-200d-1f9bc':0, '1f9d1-1f3fc-200d-1f9bc':0, '1f9d1-1f3fd-200d-1f9bc':0, '1f9d1-1f3fe-200d-1f9bc':0, '1f9d1-1f3ff-200d-1f9bc':0, '1f9d1-1f3fb-200d-1f9bd':0, '1f9d1-1f3fc-200d-1f9bd':0, '1f9d1-1f3fd-200d-1f9bd':0, '1f9d1-1f3fe-200d-1f9bd':0, '1f9d1-1f3ff-200d-1f9bd':0, '1f9d1-1f3fb-200d-2695':0, '1f9d1-1f3fc-200d-2695':0, '1f9d1-1f3fd-200d-2695':0, '1f9d1-1f3fe-200d-2695':0, '1f9d1-1f3ff-200d-2695':0, '1f9d1-1f3fb-200d-2696':0, '1f9d1-1f3fc-200d-2696':0, '1f9d1-1f3fd-200d-2696':0, '1f9d1-1f3fe-200d-2696':0, '1f9d1-1f3ff-200d-2696':0, '1f9d1-1f3fb-200d-2708':0, '1f9d1-1f3fc-200d-2708':0, '1f9d1-1f3fd-200d-2708':0, '1f9d1-1f3fe-200d-2708':0, '1f9d1-1f3ff-200d-2708':0, '1f9d1-1f3fb':0, '1f9d1-1f3fc':0, '1f9d1-1f3fd':0, '1f9d1-1f3fe':0, '1f9d1-1f3ff':0, '1f9d2-1f3fb':0, '1f9d2-1f3fc':0, '1f9d2-1f3fd':0, '1f9d2-1f3fe':0, '1f9d2-1f3ff':0, '1f9d3-1f3fb':0, '1f9d3-1f3fc':0, '1f9d3-1f3fd':0, '1f9d3-1f3fe':0, '1f9d3-1f3ff':0, '1f9d4-1f3fb-200d-2640':0, '1f9d4-1f3fc-200d-2640':0, '1f9d4-1f3fd-200d-2640':0, '1f9d4-1f3fe-200d-2640':0, '1f9d4-1f3ff-200d-2640':0, '1f9d4-1f3fb-200d-2642':0, '1f9d4-1f3fc-200d-2642':0, '1f9d4-1f3fd-200d-2642':0, '1f9d4-1f3fe-200d-2642':0, '1f9d4-1f3ff-200d-2642':0, '1f9d4-1f3fb':0, '1f9d4-1f3fc':0, '1f9d4-1f3fd':0, '1f9d4-1f3fe':0, '1f9d4-1f3ff':0, '1f9d5-1f3fb':0, '1f9d5-1f3fc':0, '1f9d5-1f3fd':0, '1f9d5-1f3fe':0, '1f9d5-1f3ff':0, '1f9d6-1f3fb-200d-2640':0, '1f9d6-1f3fc-200d-2640':0, '1f9d6-1f3fd-200d-2640':0, '1f9d6-1f3fe-200d-2640':0, '1f9d6-1f3ff-200d-2640':0, '1f9d6-1f3fb-200d-2642':0, '1f9d6-1f3fc-200d-2642':0, '1f9d6-1f3fd-200d-2642':0, '1f9d6-1f3fe-200d-2642':0, '1f9d6-1f3ff-200d-2642':0, '1f9d6-1f3fb':0, '1f9d6-1f3fc':0, '1f9d6-1f3fd':0, '1f9d6-1f3fe':0, '1f9d6-1f3ff':0, '1f9d7-1f3fb-200d-2640':0, '1f9d7-1f3fc-200d-2640':0, '1f9d7-1f3fd-200d-2640':0, '1f9d7-1f3fe-200d-2640':0, '1f9d7-1f3ff-200d-2640':0, '1f9d7-1f3fb-200d-2642':0, '1f9d7-1f3fc-200d-2642':0, '1f9d7-1f3fd-200d-2642':0, '1f9d7-1f3fe-200d-2642':0, '1f9d7-1f3ff-200d-2642':0, '1f9d7-1f3fb':0, '1f9d7-1f3fc':0, '1f9d7-1f3fd':0, '1f9d7-1f3fe':0, '1f9d7-1f3ff':0, '1f9d8-1f3fb-200d-2640':0, '1f9d8-1f3fc-200d-2640':0, '1f9d8-1f3fd-200d-2640':0, '1f9d8-1f3fe-200d-2640':0, '1f9d8-1f3ff-200d-2640':0, '1f9d8-1f3fb-200d-2642':0, '1f9d8-1f3fc-200d-2642':0, '1f9d8-1f3fd-200d-2642':0, '1f9d8-1f3fe-200d-2642':0, '1f9d8-1f3ff-200d-2642':0, '1f9d8-1f3fb':0, '1f9d8-1f3fc':0, '1f9d8-1f3fd':0, '1f9d8-1f3fe':0, '1f9d8-1f3ff':0, '1f9d9-1f3fb-200d-2640':0, '1f9d9-1f3fc-200d-2640':0, '1f9d9-1f3fd-200d-2640':0, '1f9d9-1f3fe-200d-2640':0, '1f9d9-1f3ff-200d-2640':0, '1f9d9-1f3fb-200d-2642':0, '1f9d9-1f3fc-200d-2642':0, '1f9d9-1f3fd-200d-2642':0, '1f9d9-1f3fe-200d-2642':0, '1f9d9-1f3ff-200d-2642':0, '1f9d9-1f3fb':0, '1f9d9-1f3fc':0, '1f9d9-1f3fd':0, '1f9d9-1f3fe':0, '1f9d9-1f3ff':0, '1f9da-1f3fb-200d-2640':0, '1f9da-1f3fc-200d-2640':0, '1f9da-1f3fd-200d-2640':0, '1f9da-1f3fe-200d-2640':0, '1f9da-1f3ff-200d-2640':0, '1f9da-1f3fb-200d-2642':0, '1f9da-1f3fc-200d-2642':0, '1f9da-1f3fd-200d-2642':0, '1f9da-1f3fe-200d-2642':0, '1f9da-1f3ff-200d-2642':0, '1f9da-1f3fb':0, '1f9da-1f3fc':0, '1f9da-1f3fd':0, '1f9da-1f3fe':0, '1f9da-1f3ff':0, '1f9db-1f3fb-200d-2640':0, '1f9db-1f3fc-200d-2640':0, '1f9db-1f3fd-200d-2640':0, '1f9db-1f3fe-200d-2640':0, '1f9db-1f3ff-200d-2640':0, '1f9db-1f3fb-200d-2642':0, '1f9db-1f3fc-200d-2642':0, '1f9db-1f3fd-200d-2642':0, '1f9db-1f3fe-200d-2642':0, '1f9db-1f3ff-200d-2642':0, '1f9db-1f3fb':0, '1f9db-1f3fc':0, '1f9db-1f3fd':0, '1f9db-1f3fe':0, '1f9db-1f3ff':0, '1f9dc-1f3fb-200d-2640':0, '1f9dc-1f3fc-200d-2640':0, '1f9dc-1f3fd-200d-2640':0, '1f9dc-1f3fe-200d-2640':0, '1f9dc-1f3ff-200d-2640':0, '1f9dc-1f3fb-200d-2642':0, '1f9dc-1f3fc-200d-2642':0, '1f9dc-1f3fd-200d-2642':0, '1f9dc-1f3fe-200d-2642':0, '1f9dc-1f3ff-200d-2642':0, '1f9dc-1f3fb':0, '1f9dc-1f3fc':0, '1f9dc-1f3fd':0, '1f9dc-1f3fe':0, '1f9dc-1f3ff':0, '1f9dd-1f3fb-200d-2640':0, '1f9dd-1f3fc-200d-2640':0, '1f9dd-1f3fd-200d-2640':0, '1f9dd-1f3fe-200d-2640':0, '1f9dd-1f3ff-200d-2640':0, '1f9dd-1f3fb-200d-2642':0, '1f9dd-1f3fc-200d-2642':0, '1f9dd-1f3fd-200d-2642':0, '1f9dd-1f3fe-200d-2642':0, '1f9dd-1f3ff-200d-2642':0, '1f9dd-1f3fb':0, '1f9dd-1f3fc':0, '1f9dd-1f3fd':0, '1f9dd-1f3fe':0, '1f9dd-1f3ff':0, '261d-1f3fb':0, '261d-1f3fc':0, '261d-1f3fd':0, '261d-1f3fe':0, '261d-1f3ff':0, '26f9-1f3fb-200d-2640':0, '26f9-1f3fc-200d-2640':0, '26f9-1f3fd-200d-2640':0, '26f9-1f3fe-200d-2640':0, '26f9-1f3ff-200d-2640':0, '26f9-1f3fb-200d-2642':0, '26f9-1f3fc-200d-2642':0, '26f9-1f3fd-200d-2642':0, '26f9-1f3fe-200d-2642':0, '26f9-1f3ff-200d-2642':0, '26f9-1f3fb':0, '26f9-1f3fc':0, '26f9-1f3fd':0, '26f9-1f3fe':0, '26f9-1f3ff':0, '270a-1f3fb':0, '270a-1f3fc':0, '270a-1f3fd':0, '270a-1f3fe':0, '270a-1f3ff':0, '270b-1f3fb':0, '270b-1f3fc':0, '270b-1f3fd':0, '270b-1f3fe':0, '270b-1f3ff':0, '270c-1f3fb':0, '270c-1f3fc':0, '270c-1f3fd':0, '270c-1f3fe':0, '270c-1f3ff':0, '270d-1f3fb':0, '270d-1f3fc':0, '270d-1f3fd':0, '270d-1f3fe':0, '270d-1f3ff':0}};\n\nconst Emoji: {[emoji: string]: number} = EmojiVersions[''];\nfor(const version in EmojiVersions) {\n if(version) {\n Object.assign(Emoji, EmojiVersions[version as EMOJI_VERSION]);\n }\n}\n\nexport default Emoji;\n\n/* Emoji[\"00a9-fe0f\"] = 6362;\nEmoji[\"00ae-fe0f\"] = 6363;\nEmoji[\"2122-fe0f\"] = 6364; */\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport const FontFamily = 'Roboto, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif';\nexport const FontSize = '16px';\nexport const FontWeight = '400';\n","const IS_IMAGE_BITMAP_SUPPORTED = typeof(ImageBitmap) !== 'undefined';\n\nexport default IS_IMAGE_BITMAP_SUPPORTED;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// * Jolly Cobra's animation.ts\n\nimport {fastRaf} from './schedulers';\nimport deferredPromise, {CancellablePromise} from './cancellablePromise';\n\ninterface AnimationInstance {\n isCancelled: boolean;\n deferred: CancellablePromise<void>\n}\n\ntype AnimationInstanceKey = any;\nconst instances: Map<AnimationInstanceKey, AnimationInstance> = new Map();\n\nexport function createAnimationInstance(key: AnimationInstanceKey) {\n cancelAnimationByKey(key);\n\n const instance: AnimationInstance = {\n isCancelled: false,\n deferred: deferredPromise<void>()\n };\n\n instances.set(key, instance);\n instance.deferred.then(() => {\n if(getAnimationInstance(key) === instance) {\n instances.delete(key);\n }\n });\n\n return instance;\n}\n\nexport function getAnimationInstance(key: AnimationInstanceKey) {\n return instances.get(key);\n}\n\nexport function cancelAnimationByKey(key: AnimationInstanceKey) {\n const instance = getAnimationInstance(key);\n if(instance) {\n instance.isCancelled = true;\n instance.deferred.resolve();\n }\n}\n\nexport function animateSingle(tick: Function, key: AnimationInstanceKey, instance?: AnimationInstance) {\n if(!instance) {\n instance = createAnimationInstance(key);\n }\n\n fastRaf(() => {\n if(instance.isCancelled) {\n return;\n }\n\n if(tick()) {\n animateSingle(tick, key, instance);\n } else {\n instance.deferred.resolve();\n }\n });\n\n return instance.deferred;\n}\n\nexport function animate(tick: Function) {\n fastRaf(() => {\n if(tick()) {\n animate(tick);\n }\n });\n}\n","export default function accumulate(arr: number[], initialValue: number) {\n return arr.reduce((acc, value) => acc + value, initialValue);\n}\n","type K = boolean;\nexport default async function filterAsync<T>(arr: T[], callback: (item: T, idx: number, arr: T[]) => Promise<K> | K) {\n const promises = arr.map(async(item, idx, arr) => {\n if(await callback(item, idx, arr)) {\n return item;\n }\n });\n\n return (await Promise.all(promises)).filter(Boolean);\n}\n","export default function findAndSpliceAll<T>(array: Array<T>, verify: (value: T, index: number, arr: typeof array) => boolean) {\n const out: typeof array = [];\n let idx = -1;\n while((idx = array.findIndex(verify)) !== -1) {\n out.push(array.splice(idx, 1)[0]);\n }\n\n return out;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function partition<T>(arr: T[], callback: (item: T, idx: number, arr: T[]) => boolean) {\n const good: T[] = [], bad: T[] = [];\n for(let i = 0, length = arr.length; i < length; ++i) {\n const item = arr[i];\n (callback(item, i, arr) ? good : bad).push(item);\n }\n\n return [good, bad];\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nconst ASSETS_PATH = 'assets/audio/';\n\nexport default class AudioAssetPlayer<AssetName extends string> {\n private audio: HTMLAudioElement;\n private tempId: number;\n private assetName: AssetName;\n\n constructor(private assets: AssetName[]) {\n this.tempId = 0;\n }\n\n public playSound(name: AssetName, loop = false) {\n ++this.tempId;\n this.assetName = name;\n\n try {\n const audio = this.createAudio();\n audio.autoplay = true;\n audio.src = ASSETS_PATH + name;\n audio.loop = loop;\n audio.play();\n } catch(e) {\n console.error('playSound', name, e);\n }\n }\n\n public playSoundIfDifferent(name: AssetName, loop?: boolean) {\n if(this.assetName !== name) {\n this.playSound(name, loop);\n }\n }\n\n public createAudio() {\n let {audio} = this;\n if(audio) {\n return audio;\n }\n\n audio = this.audio = new Audio();\n audio.play();\n return audio;\n }\n\n public stopSound() {\n if(!this.audio) {\n return;\n }\n\n this.audio.pause();\n }\n\n public cancelDelayedPlay() {\n ++this.tempId;\n }\n\n public playSoundWithTimeout(name: AssetName, loop: boolean, timeout: number) {\n // timeout = 0;\n const tempId = ++this.tempId;\n setTimeout(() => {\n if(this.tempId !== tempId) {\n return;\n }\n\n this.playSound(name, loop);\n }, timeout);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport readBlobAs from './readBlobAs';\n\nexport default function readBlobAsDataURL(blob: Blob) {\n return readBlobAs(blob, 'readAsDataURL');\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport deferredPromise, {CancellablePromise} from './cancellablePromise';\nimport {getHeavyAnimationPromise} from '../hooks/useHeavyAnimationCheck';\nimport {fastRaf} from './schedulers';\nimport {ArgumentTypes} from '../types';\n\ntype HeavyQueue<T extends HeavyQueue<any>> = {\n items: ArgumentTypes<T['process']>[],\n process: (...args: any[]) => ReturnType<T['process']>,\n context: any,\n promise?: CancellablePromise<ReturnType<T['process']>[]>\n};\nconst heavyQueue: HeavyQueue<any>[] = [];\nlet processingQueue = false;\n\nexport default function addHeavyTask<T extends HeavyQueue<T>>(queue: T, method: 'push' | 'unshift' = 'push') {\n if(!queue.items.length) {\n return Promise.resolve([]) as typeof promise;\n }\n\n const promise = queue.promise = deferredPromise();\n heavyQueue[method](queue);\n processHeavyQueue();\n\n return promise;\n}\n\nfunction processHeavyQueue() {\n if(!processingQueue) {\n const queue = heavyQueue.shift();\n timedChunk(queue).finally(() => {\n processingQueue = false;\n if(heavyQueue.length) {\n processHeavyQueue();\n }\n });\n }\n}\n\nfunction timedChunk<T extends HeavyQueue<T>>(queue: HeavyQueue<T>) {\n if(!queue.items.length) {\n queue.promise.resolve([] as any);\n return Promise.resolve([]);\n }\n\n const todo = queue.items.slice();\n const results: ReturnType<T['process']>[] = [];\n\n return new Promise<typeof results>((resolve, reject) => {\n const f = async() => {\n const start = performance.now();\n\n do {\n await getHeavyAnimationPromise();\n const possiblePromise = queue.process.apply(queue.context, todo.shift());\n let realResult: typeof results[0];\n // @ts-ignore\n if(possiblePromise instanceof Promise) {\n try {\n realResult = await possiblePromise;\n } catch(err) {\n reject(err);\n return;\n }\n } else {\n realResult = possiblePromise;\n }\n\n results.push(realResult);\n } while(todo.length > 0 && (performance.now() - start) < 6);\n\n if(todo.length > 0) {\n fastRaf(f);\n // setTimeout(f, 25);\n } else {\n resolve(results);\n }\n };\n\n fastRaf(f);\n // setTimeout(f, 25);\n }).then(queue.promise.resolve, queue.promise.reject);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type fastBlur from '../vendor/fastBlur';\nimport addHeavyTask from './heavyQueue';\nimport IS_CANVAS_FILTER_SUPPORTED from '../environment/canvasFilterSupport';\n\nconst RADIUS = 2;\nconst ITERATIONS = 2;\n\nlet requireBlurPromise: Promise<any>;\nlet fastBlurFunc: typeof fastBlur;\nif(!IS_CANVAS_FILTER_SUPPORTED) {\n requireBlurPromise = import('../vendor/fastBlur').then((m) => {\n fastBlurFunc = m.default;\n });\n} else {\n requireBlurPromise = Promise.resolve();\n}\n\nfunction processBlurNext(\n img: HTMLImageElement,\n radius: number,\n iterations: number,\n canvas: HTMLCanvasElement = document.createElement('canvas')\n) {\n canvas.width = img.width;\n canvas.height = img.height;\n\n const ctx = canvas.getContext('2d', {alpha: false});\n if(IS_CANVAS_FILTER_SUPPORTED) {\n ctx.filter = `blur(${radius}px)`;\n ctx.drawImage(img, -radius * 2, -radius * 2, canvas.width + radius * 4, canvas.height + radius * 4);\n } else {\n ctx.drawImage(img, 0, 0);\n fastBlurFunc(ctx, 0, 0, canvas.width, canvas.height, radius, iterations);\n }\n\n return canvas;\n}\n\ntype CacheValue = {canvas: HTMLCanvasElement, promise: Promise<void>};\nconst cache: Map<string, CacheValue> = new Map();\nconst CACHE_SIZE = 150;\n\nexport default function blur(dataUri: string, radius: number = RADIUS, iterations: number = ITERATIONS) {\n if(!dataUri) {\n throw 'no dataUri for blur: ' + dataUri;\n }\n\n if(cache.size > CACHE_SIZE) {\n cache.clear();\n }\n\n const canvas = document.createElement('canvas');\n canvas.className = 'canvas-thumbnail';\n\n let cached = cache.get(dataUri);\n if(!cached) {\n const promise: CacheValue['promise'] = new Promise((resolve) => {\n // return resolve(dataUri);\n requireBlurPromise.then(() => {\n const img = new Image();\n img.onload = () => {\n // if(IS_CANVAS_FILTER_SUPPORTED) {\n // resolve(processBlurNext(img, radius, iterations));\n // } else {\n const promise = addHeavyTask({\n items: [[img, radius, iterations, canvas]],\n context: null,\n process: processBlurNext\n }, 'unshift');\n\n promise.then(() => {\n resolve();\n });\n // }\n };\n img.src = dataUri;\n });\n });\n\n cache.set(dataUri, cached = {\n canvas,\n promise\n });\n } else {\n canvas.width = cached.canvas.width;\n canvas.height = cached.canvas.height;\n cached.promise.then(() => {\n canvas.getContext('2d').drawImage(cached.canvas, 0, 0, canvas.width, canvas.height);\n });\n }\n\n return {\n ...cached,\n canvas\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {IS_SAFARI} from '../../environment/userAgent';\nimport bytesFromHex from './bytesFromHex';\nimport bytesToDataURL from './bytesToDataURL';\nimport convertToUint8Array from './convertToUint8Array';\n\nconst JPEG_HEADER_HEX = 'ffd8ffe000104a46494600010100000100010000ffdb004300281c1e231e19282321232d2b28303c64413c37373c7b585d4964918099968f808c8aa0b4e6c3a0aadaad8a8cc8ffcbdaeef5ffffff9bc1fffffffaffe6fdfff8ffdb0043012b2d2d3c353c76414176f8a58ca5f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8ffc00011080000000003012200021101031101ffc4001f0000010501010101010100000000000000000102030405060708090a0bffc400b5100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9faffc4001f0100030101010101010101010000000000000102030405060708090a0bffc400b51100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00';\n\nconst JPEG_HEADER = bytesFromHex(JPEG_HEADER_HEX);\nconst JPEG_TAIL = bytesFromHex('ffd9');\n\nexport function getPreviewBytesFromURL(url: string) {\n const needle = 'base64,';\n const sliced = url.slice(url.indexOf(needle) + needle.length);\n const jpegBytes = [...atob(sliced)].map((char) => char.charCodeAt(0));\n\n return new Uint8Array(jpegBytes);\n // console.log('getPreviewBytesFromURL', bytesToHex(jpegBytes));\n\n // const n = JPEG_HEADER_HEX.slice(-10);\n // const one = jpegBytes[164];\n // const two = jpegBytes[166];\n\n // const body = jpegBytes.slice(bytesToHex(jpegBytes).indexOf(n) / 2 + n.length / 2/* JPEG_HEADER.length */, jpegBytes.length - JPEG_TAIL.length);\n // const original = new Uint8Array([\n // 0xFF,\n // one,\n // two,\n // ...body\n // ]);\n\n // console.log(bytesToHex(body));\n\n // return original;\n}\n\nexport default function getPreviewURLFromBytes(bytes: Uint8Array | number[], isSticker = false) {\n let arr: Uint8Array;\n if(!isSticker && bytes[0] === 0x1) {\n arr = new Uint8Array(JPEG_HEADER.concat(Array.from(bytes.slice(3)), JPEG_TAIL));\n arr[164] = bytes[1];\n arr[166] = bytes[2];\n } else {\n arr = convertToUint8Array(bytes);\n }\n\n let mimeType: string;\n if(isSticker) {\n mimeType = IS_SAFARI ? 'image/png' : 'image/webp';\n } else {\n mimeType = 'image/jpeg';\n }\n\n const dataURL = bytesToDataURL(arr, mimeType);\n return dataURL;\n}\n","export default function bytesToDataURL(bytes: Uint8Array, mimeType: string = 'image/jpeg') {\n return `data:${mimeType};base64,${btoa(String.fromCharCode(...bytes))}`;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/zhukov/webogram\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\n * https://github.com/zhukov/webogram/blob/master/LICENSE\n */\n\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport {makeMediaSize} from './mediaSize';\n\nexport default function calcImageInBox(imageW: number, imageH: number, boxW: number, boxH: number, noZoom = true) {\n if(imageW < boxW && imageH < boxH && noZoom) {\n return makeMediaSize(imageW, imageH);\n }\n\n let boxedImageW = boxW;\n let boxedImageH = boxH;\n\n if((imageW / imageH) > (boxW / boxH)) {\n boxedImageH = (imageH * boxW / imageW) | 0;\n } else {\n boxedImageW = (imageW * boxH / imageH) | 0;\n if(boxedImageW > boxW) {\n boxedImageH = (boxedImageH * boxW / boxedImageW) | 0;\n boxedImageW = boxW;\n }\n }\n\n // if (Config.Navigator.retina) {\n // imageW = Math.floor(imageW / 2)\n // imageH = Math.floor(imageH / 2)\n // }\n\n if(noZoom && boxedImageW >= imageW && boxedImageH >= imageH) {\n boxedImageW = imageW;\n boxedImageH = imageH;\n }\n\n return makeMediaSize(boxedImageW, boxedImageH);\n}\n\nMOUNT_CLASS_TO.calcImageInBox = calcImageInBox;\n","export default function drawCircle(ctx: CanvasRenderingContext2D, x: number, y: number, radius: number, fill?: boolean, stroke?: boolean) {\n const dpr = ctx.canvas.dpr;\n if(dpr) {\n x *= dpr;\n y *= dpr;\n radius *= dpr;\n }\n\n ctx.beginPath();\n ctx.arc(x, y, radius, 0, 2 * Math.PI, false);\n ctx.closePath();\n\n if(fill) {\n ctx.fill();\n }\n\n if(stroke) {\n ctx.stroke();\n }\n}\n\nexport function drawCircleFromStart(ctx: CanvasRenderingContext2D, x: number, y: number, radius: number, fill?: boolean, stroke?: boolean) {\n return drawCircle(ctx, x + radius, y + radius, radius, fill, stroke);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// import { MOUNT_CLASS_TO } from \"../../config/debug\";\n\nlet context: CanvasRenderingContext2D;\n/**\n * Get the text width\n * @param {string} text\n * @param {string} font\n */\nexport default function getTextWidth(text: string, font: string) {\n // const perf = performance.now();\n if(!context) {\n const canvas = document.createElement('canvas');\n context = canvas.getContext('2d', {alpha: false});\n }\n\n if(context.font !== font) {\n context.font = font;\n }\n\n // context.font = font;\n const metrics = context.measureText(text);\n // console.log('getTextWidth perf:', performance.now() - perf);\n return metrics.width;\n // return Math.round(metrics.width);\n}\n\n// MOUNT_CLASS_TO && (MOUNT_CLASS_TO.getTextWidth = getTextWidth);\n","import type {MediaSize} from '../mediaSize';\nimport IS_IMAGE_BITMAP_SUPPORTED from '../../environment/imageBitmapSupport';\n\nexport default function scaleMediaElement<T extends {\n media: CanvasImageSource,\n mediaSize?: MediaSize,\n boxSize?: MediaSize,\n quality?: number,\n mimeType?: 'image/jpeg' | 'image/png',\n size?: MediaSize,\n toDataURL?: boolean\n}>(options: T): Promise<T['toDataURL'] extends true ? {url: string, size: MediaSize} : {blob: Blob, size: MediaSize}> {\n return new Promise(async(resolve) => {\n const canvas = document.createElement('canvas');\n const size = options.size ?? options.mediaSize.aspectFitted(options.boxSize);\n const dpr = window.devicePixelRatio && 1;\n canvas.width = size.width * dpr;\n canvas.height = size.height * dpr;\n const ctx = canvas.getContext('2d');\n\n let source: CanvasImageSource;\n if(IS_IMAGE_BITMAP_SUPPORTED) {\n source = await createImageBitmap(options.media, {resizeWidth: size.width, resizeHeight: size.height});\n } else {\n source = options.media;\n }\n\n ctx.drawImage(source, 0, 0, canvas.width, canvas.height);\n\n if(IS_IMAGE_BITMAP_SUPPORTED) {\n (source as ImageBitmap)?.close();\n }\n\n const mimeType = options.mimeType ?? 'image/jpeg';\n const quality = options.quality ?? 1;\n if(options.toDataURL) {\n const url = canvas.toDataURL(mimeType, quality);\n resolve({url, size} as any);\n } else {\n canvas.toBlob((blob) => {\n resolve({blob, size} as any);\n }, mimeType, quality);\n }\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/zhukov/webogram\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\n * https://github.com/zhukov/webogram/blob/master/LICENSE\n */\n\nimport LatinizeMap from '../config/latinizeMap';\n\nexport const badCharsRe = /[`~!@#$%^&*()\\-_=+\\[\\]\\\\|{}'\";:\\/?.>,<]+/g;\nconst trimRe = /^\\s+|\\s$/g;\n\nconst C2L: {[k: string]: string} = {\n 'й': 'q',\n 'ц': 'w',\n 'у': 'e',\n 'к': 'r',\n 'е': 't',\n 'н': 'y',\n 'г': 'u',\n 'ш': 'i',\n 'щ': 'o',\n 'з': 'p',\n 'х': '[',\n 'ъ': ']',\n 'ф': 'a',\n 'ы': 's',\n 'в': 'd',\n 'а': 'f',\n 'п': 'g',\n 'р': 'h',\n 'о': 'j',\n 'л': 'k',\n 'д': 'l',\n 'ж': ';',\n 'э': '\\'',\n 'я': 'z',\n 'ч': 'x',\n 'с': 'c',\n 'м': 'v',\n 'и': 'b',\n 'т': 'n',\n 'ь': 'm',\n 'б': ',',\n 'ю': '.',\n '.': '/'\n};\n\nexport function clearBadCharsAndTrim(text: string) {\n return text.replace(badCharsRe, '').replace(trimRe, '');\n}\n\nexport function fixCyrillic(text: string) {\n return text.toLowerCase().replace(/[\\wа-я]/g, (ch) => {\n const latinizeCh = C2L[ch];\n return latinizeCh ?? ch;\n });\n}\n\nexport function latinizeString(text: string) {\n return text.replace(/[^A-Za-z0-9]/g, (ch) => {\n const latinizeCh = LatinizeMap[ch];\n return latinizeCh ?? ch;\n });\n}\n\nexport default function cleanSearchText(text: string, latinize = true) {\n return processSearchText(text, {\n clearBadChars: true,\n latinize,\n ignoreCase: true\n });\n}\n\nexport type ProcessSearchTextOptions = Partial<{\n clearBadChars: boolean,\n latinize: boolean,\n ignoreCase: boolean,\n includeTag: boolean\n}>;\n\nexport function processSearchText(text: string, options: ProcessSearchTextOptions = {}) {\n const hasTag = options.includeTag && text.charAt(0) === '%';\n const originalText = text;\n if(options.clearBadChars) text = clearBadCharsAndTrim(text);\n if(options.latinize) text = latinizeString(text);\n if(options.ignoreCase) text = text.toLowerCase();\n if(hasTag) text = '%' + text;\n if(options.latinize) text += '\\x01' + fixCyrillic(originalText);\n return text;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// https://stackoverflow.com/a/30810322\nfunction fallbackCopyTextToClipboard(text: string) {\n var textArea = document.createElement('textarea');\n textArea.value = text;\n\n // Avoid scrolling to bottom\n textArea.style.top = '0';\n textArea.style.left = '0';\n textArea.style.position = 'fixed';\n\n document.body.appendChild(textArea);\n textArea.focus();\n textArea.select();\n\n try {\n document.execCommand('copy');\n // const successful = document.execCommand('copy');\n // const msg = successful ? 'successful' : 'unsuccessful';\n // console.log('Fallback: Copying text command was ' + msg);\n } catch(err) {\n // console.error('Fallback: Oops, unable to copy', err);\n }\n\n document.body.removeChild(textArea);\n}\n\nexport function copyTextToClipboard(text: string) {\n if(!navigator.clipboard) {\n fallbackCopyTextToClipboard(text);\n return;\n }\n\n navigator.clipboard.writeText(text).catch((err) => {\n console.error('clipboard error', err);\n fallbackCopyTextToClipboard(text);\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport mediaSizes from './mediaSizes';\nimport OverlayClickHandler from './overlayClickHandler';\n\nclass ContextMenuController extends OverlayClickHandler {\n constructor() {\n super('menu', true);\n\n mediaSizes.addEventListener('resize', () => {\n if(this.element) {\n this.close();\n }\n\n /* if(openedMenu && (openedMenu.style.top || openedMenu.style.left)) {\n const rect = openedMenu.getBoundingClientRect();\n const {innerWidth, innerHeight} = window;\n\n console.log(innerWidth, innerHeight, rect);\n } */\n });\n }\n\n public isOpened() {\n return !!this.element;\n }\n\n private onMouseMove = (e: MouseEvent) => {\n const rect = this.element.getBoundingClientRect();\n const {clientX, clientY} = e;\n\n const diffX = clientX >= rect.right ? clientX - rect.right : rect.left - clientX;\n const diffY = clientY >= rect.bottom ? clientY - rect.bottom : rect.top - clientY;\n\n if(diffX >= 100 || diffY >= 100) {\n this.close();\n // openedMenu.parentElement.click();\n }\n // console.log('mousemove', diffX, diffY);\n };\n\n public close() {\n if(this.element) {\n this.element.classList.remove('active');\n this.element.parentElement.classList.remove('menu-open');\n }\n\n super.close();\n\n if(!IS_TOUCH_SUPPORTED) {\n window.removeEventListener('mousemove', this.onMouseMove);\n }\n }\n\n public openBtnMenu(element: HTMLElement, onClose?: () => void) {\n super.open(element);\n\n this.element.classList.add('active', 'was-open');\n this.element.parentElement.classList.add('menu-open');\n\n if(onClose) {\n this.addEventListener('toggle', onClose, {once: true});\n }\n\n if(!IS_TOUCH_SUPPORTED) {\n window.addEventListener('mousemove', this.onMouseMove);\n }\n }\n}\n\nconst contextMenuController = new ContextMenuController();\nexport default contextMenuController;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport I18n, {i18n} from '../lib/langPack';\n\nexport const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\nexport const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n\nexport const ONE_DAY = 86400;\n\n// https://stackoverflow.com/a/6117889\nexport const getWeekNumber = (date: Date) => {\n const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n const dayNum = d.getUTCDay() || 7;\n d.setUTCDate(d.getUTCDate() + 4 - dayNum);\n const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));\n return Math.ceil((((d.getTime() - yearStart.getTime()) / ONE_DAY) + 1) / 7);\n};\n\nexport function formatDateAccordingToTodayNew(time: Date) {\n const today = new Date();\n const now = today.getTime() / 1000 | 0;\n const timestamp = time.getTime() / 1000 | 0;\n\n const options: Intl.DateTimeFormatOptions = {};\n if((now - timestamp) < ONE_DAY && today.getDate() === time.getDate()) { // if the same day\n options.hour = options.minute = '2-digit';\n } else if(today.getFullYear() !== time.getFullYear()) { // different year\n options.year = options.day = 'numeric';\n options.month = '2-digit';\n } else if((now - timestamp) < (ONE_DAY * 7) && getWeekNumber(today) === getWeekNumber(time)) { // current week\n options.weekday = 'short';\n } else { // same year\n options.month = 'short';\n options.day = 'numeric';\n }\n\n return new I18n.IntlDateElement({\n date: time,\n options\n }).element;\n}\n\nexport function formatFullSentTimeRaw(timestamp: number, options: {\n capitalize?: boolean\n} = {}) {\n const date = new Date();\n const time = new Date(timestamp * 1000);\n const now = date.getTime() / 1000;\n\n const timeEl = formatTime(time);\n\n let dateEl: Node | string;\n if((now - timestamp) < ONE_DAY && date.getDate() === time.getDate()) { // if the same day\n dateEl = i18n(options.capitalize ? 'Date.Today' : 'Peer.Status.Today');\n } else if((now - timestamp) < (ONE_DAY * 2) && (date.getDate() - 1) === time.getDate()) { // yesterday\n dateEl = i18n(options.capitalize ? 'Yesterday' : 'Peer.Status.Yesterday');\n\n if(options.capitalize) {\n (dateEl as HTMLElement).style.textTransform = 'capitalize';\n }\n } else if(date.getFullYear() !== time.getFullYear()) { // different year\n dateEl = new I18n.IntlDateElement({\n date: time,\n options: {\n month: 'short',\n day: 'numeric',\n year: 'numeric'\n }\n }).element;\n // dateStr = months[time.getMonth()].slice(0, 3) + ' ' + time.getDate() + ', ' + time.getFullYear();\n } else {\n dateEl = new I18n.IntlDateElement({\n date: time,\n options: {\n month: 'short',\n day: 'numeric'\n }\n }).element;\n // dateStr = months[time.getMonth()].slice(0, 3) + ' ' + time.getDate();\n }\n\n return {dateEl, timeEl};\n}\n\nexport function formatFullSentTime(timestamp: number, capitalize = true) {\n const {dateEl, timeEl} = formatFullSentTimeRaw(timestamp, {\n capitalize\n });\n\n const fragment = document.createDocumentFragment();\n fragment.append(dateEl, ' ', i18n('ScheduleController.at'), ' ', timeEl);\n return fragment;\n}\n\nexport function formatTime(date: Date) {\n return new I18n.IntlDateElement({\n date,\n options: {\n hour: '2-digit',\n minute: '2-digit'\n }\n }).element;\n}\n\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.formatDateAccordingToTodayNew = formatDateAccordingToTodayNew);\n\nexport const getFullDate = (date: Date, options: Partial<{\n noTime: true,\n noSeconds: true,\n monthAsNumber: true,\n leadingZero: true\n}> = {}) => {\n const joiner = options.monthAsNumber ? '.' : ' ';\n const time = ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2) + (options.noSeconds ? '' : ':' + ('0' + date.getSeconds()).slice(-2));\n\n return (options.leadingZero ? ('0' + date.getDate()).slice(-2) : date.getDate()) +\n joiner + (options.monthAsNumber ? ('0' + (date.getMonth() + 1)).slice(-2) : months[date.getMonth()]) +\n joiner + date.getFullYear() +\n (options.noTime ? '' : ', ' + time);\n};\n\n// https://github.com/DrKLO/Telegram/blob/d52b2c921abd3c1e8d6368858313ad0cb0468c07/TMessagesProj/src/main/java/org/telegram/ui/Adapters/FiltersView.java\nconst minYear = 2013;\nconst yearPattern = new RegExp('20[0-9]{1,2}');\nconst monthYearOrDayPattern = new RegExp('(\\\\w{3,}) ([0-9]{0,4})', 'i');\nconst yearOrDayAndMonthPattern = new RegExp('([0-9]{0,4}) (\\\\w{2,})', 'i');\nconst shortDate = new RegExp('^([0-9]{1,4})(\\\\.| |/|\\\\-)([0-9]{1,4})$', 'i');\nconst longDate = new RegExp('^([0-9]{1,2})(\\\\.| |/|\\\\-)([0-9]{1,2})(\\\\.| |/|\\\\-)([0-9]{1,4})$', 'i');\nconst numberOfDaysEachMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nexport type DateData = {\n title: string,\n minDate: number,\n maxDate: number,\n};\nexport function fillTipDates(query: string, dates: DateData[]) {\n const q = query.trim().toLowerCase();\n\n if(q.length < 3) {\n return;\n }\n\n if('today'.indexOf(q) === 0) {\n const date = new Date();\n const year = date.getFullYear();\n const month = date.getMonth();\n const day = date.getDate();\n date.setFullYear(year, month, day);\n date.setHours(0, 0, 0);\n\n const minDate = date.getTime();\n date.setFullYear(year, month, day + 1);\n date.setHours(0, 0, 0);\n\n const maxDate = date.getTime() - 1;\n dates.push({\n title: 'Today',\n minDate,\n maxDate\n });\n return;\n }\n\n if('yesterday'.indexOf(q) === 0) {\n const date = new Date();\n const year = date.getFullYear();\n const month = date.getMonth();\n const day = date.getDate();\n date.setFullYear(year, month, day);\n date.setHours(0, 0, 0);\n\n const minDate = date.getTime() - 86400000;\n date.setFullYear(year, month, day + 1);\n date.setHours(0, 0, 0);\n\n const maxDate = date.getTime() - 86400001;\n dates.push({\n title: 'Yesterday',\n minDate,\n maxDate\n });\n return;\n }\n\n const dayOfWeek = getDayOfWeek(q);\n if(dayOfWeek >= 0) {\n const date = new Date();\n const now = date.getTime();\n const currentDay = date.getDay();\n const distance = dayOfWeek - currentDay;\n date.setDate(date.getDate() + distance);\n if(date.getTime() > now) {\n date.setTime(date.getTime() - 604800000);\n }\n const year = date.getFullYear()\n const month = date.getMonth();\n const day = date.getDate();\n date.setFullYear(year, month, day);\n date.setHours(0, 0, 0);\n\n const minDate = date.getTime();\n date.setFullYear(year, month, day + 1);\n date.setHours(0, 0, 0);\n\n const maxDate = date.getTime() - 1;\n dates.push({\n title: formatWeekLong(minDate),\n minDate,\n maxDate\n });\n return;\n }\n\n let matches: any[];\n if((matches = shortDate.exec(q)) !== null) {\n const g1 = matches[1];\n const g2 = matches[3];\n const k = parseInt(g1);\n const k1 = parseInt(g2);\n if(k > 0 && k <= 31) {\n if(k1 >= minYear && k <= 12) {\n const selectedYear = k1;\n const month = k - 1;\n createForMonthYear(dates, month, selectedYear);\n return;\n } else if(k1 <= 12) {\n const day = k - 1;\n const month = k1 - 1;\n createForDayMonth(dates, day, month);\n }\n } else if(k >= minYear && k1 <= 12) {\n const selectedYear = k;\n const month = k1 - 1;\n createForMonthYear(dates, month, selectedYear);\n }\n\n return;\n }\n\n if((matches = longDate.exec(q)) !== null) {\n const g1 = matches[1];\n const g2 = matches[3];\n const g3 = matches[5];\n if(!matches[2] === matches[4]) {\n return;\n }\n\n const day = parseInt(g1);\n const month = parseInt(g2) - 1;\n let year = parseInt(g3);\n if(year >= 10 && year <= 99) {\n year += 2000;\n }\n\n const currentYear = new Date().getFullYear();\n if(validDateForMonth(day - 1, month) && year >= minYear && year <= currentYear) {\n const date = new Date();\n date.setFullYear(year, month, day);\n date.setHours(0, 0, 0);\n\n const minDate = date.getTime();\n date.setFullYear(year, month, day + 1);\n date.setHours(0, 0, 0);\n\n const maxDate = date.getTime() - 1;\n dates.push({\n title: formatterYearMax(minDate),\n minDate,\n maxDate\n });\n return;\n }\n\n return;\n }\n\n if((matches = yearPattern.exec(q)) !== null) {\n let selectedYear = +q;\n const currentYear = new Date().getFullYear();\n if(selectedYear < minYear) {\n selectedYear = minYear;\n for(let i = currentYear; i >= selectedYear; i--) {\n const date = new Date();\n date.setFullYear(i, 0, 1);\n date.setHours(0, 0, 0);\n\n const minDate = date.getTime();\n date.setFullYear(i + 1, 0, 1);\n date.setHours(0, 0, 0);\n\n const maxDate = date.getTime() - 1;\n dates.push({\n title: '' + i,\n minDate,\n maxDate\n });\n }\n } else if(selectedYear <= currentYear) {\n const date = new Date();\n date.setFullYear(selectedYear, 0, 1);\n date.setHours(0, 0, 0);\n\n const minDate = date.getTime();\n date.setFullYear(selectedYear + 1, 0, 1);\n date.setHours(0, 0, 0);\n\n const maxDate = date.getTime() - 1;\n dates.push({\n title: '' + selectedYear,\n minDate,\n maxDate\n });\n }\n\n return;\n }\n\n if((matches = monthYearOrDayPattern.exec(q)) !== null) {\n const g1 = matches[1];\n const g2 = matches[2];\n const month = getMonth(g1);\n if(month >= 0) {\n const k = +g2;\n if(k > 0 && k <= 31) {\n const day = k - 1;\n createForDayMonth(dates, day, month);\n return;\n } else if(k >= minYear) {\n const selectedYear = k;\n createForMonthYear(dates, month, selectedYear);\n return;\n }\n }\n }\n\n if((matches = yearOrDayAndMonthPattern.exec(q)) !== null) {\n const g1 = matches[1];\n const g2 = matches[2];\n const month = getMonth(g2);\n if(month >= 0) {\n const k = +g1;\n if(k > 0 && k <= 31) {\n const day = k - 1;\n createForDayMonth(dates, day, month);\n return;\n } else if(k >= minYear) {\n const selectedYear = k;\n createForMonthYear(dates, month, selectedYear);\n }\n }\n }\n}\n\nfunction createForMonthYear(dates: DateData[], month: number, selectedYear: number) {\n const currentYear = new Date().getFullYear();\n const today = Date.now();\n if(selectedYear >= minYear && selectedYear <= currentYear) {\n const date = new Date();\n date.setFullYear(selectedYear, month, 1);\n date.setHours(0, 0, 0);\n const minDate = date.getTime();\n if(minDate > today) {\n return;\n }\n date.setMonth(date.getMonth() + 1);\n const maxDate = date.getTime() - 1;\n\n dates.push({\n title: formatterMonthYear(minDate),\n minDate,\n maxDate\n });\n }\n}\n\nfunction createForDayMonth(dates: DateData[], day: number, month: number) {\n if(validDateForMonth(day, month)) {\n const currentYear = new Date().getFullYear();\n const today = Date.now();\n\n for(let i = currentYear; i >= minYear; i--) {\n if(month === 1 && day === 28 && !isLeapYear(i)) {\n continue;\n }\n\n const date = new Date();\n date.setFullYear(i, month, day + 1);\n date.setHours(0, 0, 0);\n\n const minDate = date.getTime();\n if(minDate > today) {\n continue;\n }\n\n date.setFullYear(i, month, day + 2);\n date.setHours(0, 0, 0);\n const maxDate = date.getTime() - 1;\n if(i === currentYear) {\n dates.push({\n title: formatterDayMonth(minDate),\n minDate,\n maxDate\n });\n } else {\n dates.push({\n title: formatterYearMax(minDate),\n minDate,\n maxDate\n });\n }\n }\n }\n}\n\nfunction formatterMonthYear(timestamp: number) {\n const date = new Date(timestamp);\n return months[date.getMonth()].slice(0, 3) + ' ' + date.getFullYear();\n}\n\nfunction formatterDayMonth(timestamp: number) {\n const date = new Date(timestamp);\n return months[date.getMonth()].slice(0, 3) + ' ' + date.getDate();\n}\n\nfunction formatterYearMax(timestamp: number) {\n const date = new Date(timestamp);\n return ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear();\n}\n\nfunction formatWeekLong(timestamp: number) {\n const date = new Date(timestamp);\n return days[date.getDay()];\n}\n\nfunction validDateForMonth(day: number, month: number) {\n if(month >= 0 && month < 12) {\n if(day >= 0 && day < numberOfDaysEachMonth[month]) {\n return true;\n }\n }\n return false;\n}\n\nfunction isLeapYear(year: number) {\n return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0);\n}\n\nfunction getMonth(q: string) {\n /* String[] months = new String[]{\n LocaleController.getString(\"January\", R.string.January).toLowerCase(),\n LocaleController.getString(\"February\", R.string.February).toLowerCase(),\n LocaleController.getString(\"March\", R.string.March).toLowerCase(),\n LocaleController.getString(\"April\", R.string.April).toLowerCase(),\n LocaleController.getString(\"May\", R.string.May).toLowerCase(),\n LocaleController.getString(\"June\", R.string.June).toLowerCase(),\n LocaleController.getString(\"July\", R.string.July).toLowerCase(),\n LocaleController.getString(\"August\", R.string.August).toLowerCase(),\n LocaleController.getString(\"September\", R.string.September).toLowerCase(),\n LocaleController.getString(\"October\", R.string.October).toLowerCase(),\n LocaleController.getString(\"November\", R.string.November).toLowerCase(),\n LocaleController.getString(\"December\", R.string.December).toLowerCase()\n }; */\n\n /* String[] monthsEng = new String[12];\n Calendar c = Calendar.getInstance();\n for (int i = 1; i <= 12; i++) {\n c.set(0, 0, 0, 0, 0, 0);\n c.set(Calendar.MONTH, i);\n monthsEng[i - 1] = c.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.ENGLISH).toLowerCase();\n } */\n\n q = q.toLowerCase();\n for(let i = 0; i < 12; i++) {\n const month = months[i].toLowerCase();\n if(month.indexOf(q) === 0) {\n return i;\n }\n }\n return -1;\n}\n\nfunction getDayOfWeek(q: string) {\n const c = new Date();\n if(q.length <= 3) {\n return -1;\n }\n\n for(let i = 0; i < 7; i++) {\n c.setDate(c.getDate() + 1);\n\n if(formatWeekLong(c.getTime()).toLowerCase().indexOf(q) === 0) {\n return c.getDay();\n }\n }\n return -1;\n}\n\nMOUNT_CLASS_TO.fillTipDates = fillTipDates;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {toastNew} from '../../components/toast';\nimport {LangPackKey} from '../../lib/langPack';\nimport {copyTextToClipboard} from '../clipboard';\nimport cancelEvent from './cancelEvent';\nimport {attachClickEvent} from './clickEvent';\n\nconst T_ME = 'https://t.me/';\nexport default function anchorCopy(options: Partial<{\n // href: string,\n mePath: string,\n username: string\n}> = {}) {\n const anchor = document.createElement('a');\n anchor.classList.add('anchor-copy');\n\n let copyWhat: string, copyText: LangPackKey = 'LinkCopied';\n if(options.mePath) {\n const href = T_ME + options.mePath;\n copyWhat = anchor.href = anchor.innerText = href;\n }\n\n if(options.username) {\n const href = T_ME + options.username;\n anchor.href = href;\n copyWhat = anchor.innerText = '@' + options.username;\n copyText = 'UsernameCopied';\n }\n\n attachClickEvent(anchor, (e) => {\n cancelEvent(e);\n copyTextToClipboard(copyWhat ?? anchor.href);\n toastNew({langPackKey: copyText});\n });\n\n return anchor;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport {IS_APPLE} from '../../environment/userAgent';\nimport contextMenuController from '../contextMenuController';\nimport ListenerSetter, {ListenerOptions} from '../listenerSetter';\nimport cancelEvent from './cancelEvent';\n\nlet _cancelContextMenuOpening = false, _cancelContextMenuOpeningTimeout = 0;\nexport function cancelContextMenuOpening() {\n if(_cancelContextMenuOpeningTimeout) {\n clearTimeout(_cancelContextMenuOpeningTimeout);\n }\n\n _cancelContextMenuOpeningTimeout = window.setTimeout(() => {\n _cancelContextMenuOpeningTimeout = 0;\n _cancelContextMenuOpening = false;\n }, .4e3);\n\n _cancelContextMenuOpening = true;\n}\n\nexport function attachContextMenuListener({\n element,\n callback,\n listenerSetter,\n listenerOptions\n}: {\n element: HTMLElement,\n callback: (e: TouchEvent | MouseEvent) => void,\n listenerSetter?: ListenerSetter,\n listenerOptions?: ListenerOptions\n}) {\n const add = listenerSetter ? listenerSetter.add(element) : element.addEventListener.bind(element);\n const remove = listenerSetter ? listenerSetter.removeManual.bind(listenerSetter, element) : element.removeEventListener.bind(element);\n\n // can't cancel further events coming after 'contextmenu' event\n if((IS_APPLE && IS_TOUCH_SUPPORTED) || listenerOptions) {\n let timeout: number;\n\n const options: EventListenerOptions = {\n ...(listenerOptions || {}),\n capture: true\n };\n\n const onCancel = () => {\n clearTimeout(timeout);\n // @ts-ignore\n remove('touchmove', onCancel, options);\n // @ts-ignore\n remove('touchend', onCancel, options);\n // @ts-ignore\n remove('touchcancel', onCancel, options);\n };\n\n add('touchstart', (e: TouchEvent) => {\n if(e.touches.length > 1) {\n onCancel();\n return;\n }\n\n add('touchmove', onCancel, options);\n add('touchend', onCancel, options);\n add('touchcancel', onCancel, options);\n\n timeout = window.setTimeout(() => {\n if(_cancelContextMenuOpening) {\n onCancel();\n return;\n }\n\n callback(e);\n onCancel();\n\n if(contextMenuController.isOpened()) {\n add('touchend', cancelEvent, {once: true}); // * fix instant closing\n }\n }, .4e3);\n }, listenerOptions);\n\n /* if(!isSafari) {\n add('contextmenu', (e: any) => {\n cancelEvent(e);\n }, {passive: false, capture: true});\n } */\n } else {\n add('contextmenu', IS_TOUCH_SUPPORTED ? (e: any) => {\n callback(e);\n\n if(contextMenuController.isOpened()) {\n add('touchend', cancelEvent, {once: true}); // * fix instant closing\n }\n } : callback, listenerOptions);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport type GrabEvent = {x: number, y: number, isTouch?: boolean, event: TouchEvent | MouseEvent};\n\nexport default function attachGrabListeners(element: HTMLElement,\n onStart: (position: GrabEvent) => void,\n onMove: (position: GrabEvent) => void,\n onEnd?: (position: GrabEvent) => void) {\n // * Mouse\n const onMouseMove = (event: MouseEvent) => {\n onMove({x: event.pageX, y: event.pageY, event});\n };\n\n const onMouseUp = (event: MouseEvent) => {\n document.removeEventListener('mousemove', onMouseMove);\n element.addEventListener('mousedown', onMouseDown, {once: true});\n onEnd?.({x: event.pageX, y: event.pageY, event});\n };\n\n const onMouseDown = (event: MouseEvent) => {\n if(event.button !== 0) {\n element.addEventListener('mousedown', onMouseDown, {once: true});\n return;\n }\n\n onStart({x: event.pageX, y: event.pageY, event});\n onMouseMove(event);\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp, {once: true});\n };\n\n element.addEventListener('mousedown', onMouseDown, {once: true});\n\n // * Touch\n const onTouchMove = (event: TouchEvent) => {\n event.preventDefault();\n onMove({x: event.touches[0].clientX, y: event.touches[0].clientY, isTouch: true, event});\n };\n\n const onTouchEnd = (event: TouchEvent) => {\n document.removeEventListener('touchmove', onTouchMove);\n element.addEventListener('touchstart', onTouchStart, {passive: false, once: true});\n const touch = event.touches[0] || event.changedTouches[0];\n onEnd?.({x: touch.clientX, y: touch.clientY, isTouch: true, event});\n };\n\n const onTouchStart = (event: TouchEvent) => {\n onStart({x: event.touches[0].clientX, y: event.touches[0].clientY, isTouch: true, event});\n onTouchMove(event);\n\n document.addEventListener('touchmove', onTouchMove, {passive: false});\n document.addEventListener('touchend', onTouchEnd, {passive: false, once: true});\n };\n\n element.addEventListener('touchstart', onTouchStart, {passive: false, once: true});\n\n return () => {\n element.removeEventListener('mousedown', onMouseDown);\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n\n element.removeEventListener('touchstart', onTouchStart);\n document.removeEventListener('touchmove', onTouchMove);\n document.removeEventListener('touchend', onTouchEnd);\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function cancelSelection() {\n if(window.getSelection) {\n if(window.getSelection().empty) { // Chrome\n window.getSelection().empty();\n } else if(window.getSelection().removeAllRanges) { // Firefox\n window.getSelection().removeAllRanges();\n }\n // @ts-ignore\n } else if(document.selection) { // IE?\n // @ts-ignore\n document.selection.empty();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ListenerSetter from '../listenerSetter';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport simulateEvent from './dispatchEvent';\n\nlet lastMouseDownElement: HTMLElement;\ndocument.addEventListener('mousedown', (e) => {\n lastMouseDownElement = e.target as HTMLElement;\n});\n\nexport function hasMouseMovedSinceDown(e: Event) {\n if(e.isTrusted && e.type === 'click' && e.target !== lastMouseDownElement) {\n return true;\n }\n}\n\nexport const CLICK_EVENT_NAME: 'mousedown' /* | 'touchend' */ | 'click' = (IS_TOUCH_SUPPORTED ? 'mousedown' : 'click') as any;\nexport type AttachClickOptions = AddEventListenerOptions & Partial<{listenerSetter: ListenerSetter, touchMouseDown: true}>;\nexport function attachClickEvent(elem: HTMLElement | Window, callback: (e: /* TouchEvent | */MouseEvent) => void, options: AttachClickOptions = {}) {\n const add = options.listenerSetter ? options.listenerSetter.add(elem) : elem.addEventListener.bind(elem);\n const remove = options.listenerSetter ? options.listenerSetter.removeManual.bind(options.listenerSetter, elem) : elem.removeEventListener.bind(elem);\n\n options.touchMouseDown = true;\n /* if(options.touchMouseDown && CLICK_EVENT_NAME === 'touchend') {\n add('mousedown', callback, options);\n } else if(CLICK_EVENT_NAME === 'touchend') {\n const o = {...options, once: true};\n\n const onTouchStart = (e: TouchEvent) => {\n const onTouchMove = (e: TouchEvent) => {\n remove('touchmove', onTouchMove, o);\n remove('touchend', onTouchEnd, o);\n };\n\n const onTouchEnd = (e: TouchEvent) => {\n remove('touchmove', onTouchMove, o);\n callback(e);\n if(options.once) {\n remove('touchstart', onTouchStart);\n }\n };\n\n add('touchend', onTouchEnd, o);\n add('touchmove', onTouchMove, o);\n };\n\n add('touchstart', onTouchStart);\n } else {\n add(CLICK_EVENT_NAME, callback, options);\n } */\n\n if(CLICK_EVENT_NAME === 'click') {\n const cb = callback;\n callback = (e) => {\n if(hasMouseMovedSinceDown(e)) {\n return;\n }\n\n cb(e);\n };\n }\n\n add(CLICK_EVENT_NAME, callback, options);\n\n // @ts-ignore\n return () => remove(CLICK_EVENT_NAME, callback, options);\n}\n\n// export function detachClickEvent(elem: HTMLElement | Window, callback: (e: /* TouchEvent | */MouseEvent) => void, options?: AddEventListenerOptions) {\n// // if(CLICK_EVENT_NAME === 'touchend') {\n// // elem.removeEventListener('touchstart', callback, options);\n// // } else {\n// elem.removeEventListener(CLICK_EVENT_NAME, callback as any, options);\n// // }\n// }\n\nexport function simulateClickEvent(elem: HTMLElement) {\n simulateEvent(elem, CLICK_EVENT_NAME);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport EventListenerBase from '../eventListenerBase';\nimport ListenerSetter from '../listenerSetter';\nimport safeAssign from '../object/safeAssign';\nimport findUpClassName from './findUpClassName';\n\nexport default class ControlsHover extends EventListenerBase<{\n toggleControls: (show: boolean) => void\n}> {\n protected hideControlsTimeout: number;\n protected controlsLocked: boolean;\n\n protected canHideControls: () => boolean;\n protected element: HTMLElement;\n protected listenerSetter: ListenerSetter;\n protected showOnLeaveToClassName: string;\n protected ignoreClickClassName: string;\n\n constructor() {\n super(false);\n this.hideControlsTimeout = 0;\n }\n\n public setup(options: {\n element: HTMLElement,\n listenerSetter: ListenerSetter,\n canHideControls?: () => boolean,\n showOnLeaveToClassName?: string,\n ignoreClickClassName?: string\n }) {\n safeAssign(this, options);\n\n const {listenerSetter, element} = this;\n\n if(IS_TOUCH_SUPPORTED) {\n listenerSetter.add(element)('click', (e) => {\n if(this.ignoreClickClassName && findUpClassName(e.target, this.ignoreClickClassName)) {\n return;\n }\n\n this.toggleControls();\n });\n\n /* listenerSetter.add(player)('touchstart', () => {\n showControls(false);\n });\n\n listenerSetter.add(player)('touchend', () => {\n if(player.classList.contains('is-playing')) {\n showControls();\n }\n }); */\n } else {\n listenerSetter.add(element)('mousemove', () => {\n this.showControls();\n });\n\n listenerSetter.add(element)('mouseenter', () => {\n this.showControls(false);\n });\n\n listenerSetter.add(element)('mouseleave', (e) => {\n if(e.relatedTarget && this.showOnLeaveToClassName && findUpClassName(e.relatedTarget, this.showOnLeaveToClassName)) {\n this.showControls(false);\n return;\n }\n\n this.hideControls();\n });\n }\n }\n\n public hideControls = (setHideTimeout = false) => {\n if(setHideTimeout) {\n if(!this.hideControlsTimeout) {\n this.hideControlsTimeout = window.setTimeout(this.hideControls, 3e3);\n }\n\n return;\n }\n\n clearTimeout(this.hideControlsTimeout);\n this.hideControlsTimeout = 0;\n\n const isShown = this.element.classList.contains('show-controls');\n if(this.controlsLocked !== false) {\n if((this.canHideControls ? !this.canHideControls() : false) || !isShown || this.controlsLocked) {\n return;\n }\n } else if(!isShown) {\n return;\n }\n\n this.dispatchEvent('toggleControls', false);\n this.element.classList.remove('show-controls');\n };\n\n public showControls = (setHideTimeout = true) => {\n if(this.hideControlsTimeout) {\n clearTimeout(this.hideControlsTimeout);\n this.hideControlsTimeout = 0;\n } else if(!this.element.classList.contains('show-controls') && this.controlsLocked !== false) {\n this.dispatchEvent('toggleControls', true);\n this.element.classList.add('show-controls');\n }\n\n if(!setHideTimeout || this.controlsLocked) {\n return;\n }\n\n this.hideControlsTimeout = window.setTimeout(this.hideControls, 3e3);\n };\n\n public toggleControls = (show?: boolean) => {\n const isShown = this.element.classList.contains('show-controls');\n\n if(show === undefined) {\n if(isShown) this.hideControls();\n else this.showControls();\n } else if(show === isShown) return;\n else if(show === false) this.hideControls();\n else this.showControls();\n };\n\n public lockControls(visible: boolean) {\n this.controlsLocked = visible;\n\n this.element.classList.toggle('disable-hover', visible === false);\n this.toggleControls(visible);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport ButtonMenu, {ButtonMenuItemOptionsVerifiable} from '../../components/buttonMenu';\nimport filterAsync from '../array/filterAsync';\nimport callbackify from '../callbackify';\nimport contextMenuController from '../contextMenuController';\nimport ListenerSetter from '../listenerSetter';\nimport {getMiddleware, Middleware} from '../middleware';\nimport positionMenu from '../positionMenu';\nimport {attachContextMenuListener} from './attachContextMenuListener';\nimport {attachClickEvent} from './clickEvent';\n\nexport default function createContextMenu<T extends ButtonMenuItemOptionsVerifiable>({\n buttons,\n findElement,\n listenTo,\n appendTo,\n filterButtons,\n onOpen,\n onClose,\n onBeforeOpen,\n listenerSetter: attachListenerSetter,\n middleware,\n listenForClick\n}: {\n buttons: T[],\n findElement?: (e: MouseEvent | TouchEvent) => HTMLElement,\n listenTo: HTMLElement,\n appendTo?: HTMLElement,\n filterButtons?: (buttons: T[]) => Promise<T[]>,\n onOpen?: (target: HTMLElement) => any,\n onClose?: () => any,\n onBeforeOpen?: () => any,\n listenerSetter?: ListenerSetter,\n middleware?: Middleware,\n listenForClick?: boolean\n}) {\n appendTo ??= document.body;\n\n attachListenerSetter ??= new ListenerSetter();\n const listenerSetter = new ListenerSetter();\n const middlewareHelper = middleware ? middleware.create() : getMiddleware();\n let element: HTMLElement;\n\n const open = (e: MouseEvent | TouchEvent) => {\n const target = findElement ? findElement(e as any) : listenTo;\n if(!target) {\n return;\n }\n\n let _element = element;\n if(e instanceof MouseEvent || e.hasOwnProperty('preventDefault')) (e as any).preventDefault();\n if(_element && _element.classList.contains('active')) {\n return false;\n }\n if(e instanceof MouseEvent || e.hasOwnProperty('cancelBubble')) (e as any).cancelBubble = true;\n\n const r = async() => {\n await onOpen?.(target);\n\n const initResult = await init();\n if(!initResult) {\n return;\n }\n\n _element = initResult.element;\n const {cleanup, destroy} = initResult;\n\n positionMenu(e, _element);\n contextMenuController.openBtnMenu(_element, () => {\n onClose?.();\n cleanup();\n\n setTimeout(() => {\n destroy();\n }, 300);\n });\n };\n\n r();\n };\n\n attachContextMenuListener({\n element: listenTo,\n callback: open,\n listenerSetter: attachListenerSetter\n });\n\n const cleanup = () => {\n listenerSetter.removeAll();\n middlewareHelper.clean();\n };\n\n const destroy = () => {\n cleanup();\n attachListenerSetter.removeAll();\n };\n\n const init = async() => {\n cleanup();\n\n buttons.forEach((button) => button.element = undefined);\n const f = filterButtons || ((buttons: T[]) => filterAsync(buttons, (button) => {\n return button?.verify ? callbackify(button.verify(), (result) => result ?? false) : true;\n }));\n\n const filteredButtons = await f(buttons);\n if(!filteredButtons.length) {\n return;\n }\n\n const _element = element = await ButtonMenu({\n buttons: filteredButtons,\n listenerSetter\n });\n _element.classList.add('contextmenu');\n\n await onBeforeOpen?.();\n\n appendTo.append(_element);\n\n return {\n element: _element,\n cleanup,\n destroy: () => {\n _element.remove();\n }\n };\n };\n\n if(middleware) {\n middleware.onDestroy(() => {\n destroy();\n });\n }\n\n if(listenForClick) {\n attachClickEvent(listenTo, open, {listenerSetter: attachListenerSetter});\n }\n\n return {element, destroy, open};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../../lib/appManagers/appDocsManager';\nimport PopupStickers from '../../components/popups/stickers';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport rootScope from '../../lib/rootScope';\nimport createContextMenu from './createContextMenu';\nimport findUpClassName from './findUpClassName';\nimport {EmoticonsDropdown} from '../../components/emoticonsDropdown';\nimport PopupElement from '../../components/popups';\n\nexport default function createStickersContextMenu(options: {\n listenTo: HTMLElement,\n isStickerPack?: boolean,\n verifyRecent?: (target: HTMLElement) => boolean,\n appendTo?: HTMLElement,\n onOpen?: () => any,\n onClose?: () => any,\n onSend?: () => any\n}) {\n const {listenTo, isStickerPack, verifyRecent, appendTo, onOpen, onClose, onSend} = options;\n let target: HTMLElement, doc: MyDocument;\n const verifyFavoriteSticker = async(toAdd: boolean) => {\n const favedStickers = await rootScope.managers.acknowledged.appStickersManager.getFavedStickersStickers();\n if(!favedStickers.cached) {\n return false;\n }\n\n const found = (await favedStickers.result).some((_doc) => _doc.id === doc.id);\n return toAdd ? !found : found;\n };\n\n return createContextMenu({\n listenTo: listenTo,\n appendTo,\n findElement: (e) => target = findUpClassName(e.target, 'media-sticker-wrapper'),\n onOpen: async() => {\n doc = await rootScope.managers.appDocsManager.getDoc(target.dataset.docId);\n return onOpen?.();\n },\n onClose,\n buttons: [{\n icon: 'stickers',\n text: 'Context.ViewStickerSet',\n onClick: () => PopupElement.createPopup(PopupStickers, doc.stickerSetInput).show(),\n verify: () => !isStickerPack\n }, {\n icon: 'favourites',\n text: 'AddToFavorites',\n onClick: () => rootScope.managers.appStickersManager.faveSticker(doc.id, false),\n verify: () => verifyFavoriteSticker(true)\n }, {\n icon: 'favourites',\n text: 'DeleteFromFavorites',\n onClick: () => rootScope.managers.appStickersManager.faveSticker(doc.id, true),\n verify: () => verifyFavoriteSticker(false)\n }, {\n icon: 'delete',\n text: 'DeleteFromRecent',\n onClick: () => rootScope.managers.appStickersManager.saveRecentSticker(doc.id, true),\n verify: () => verifyRecent?.(target) ?? false\n }, {\n icon: 'mute',\n text: 'Chat.Send.WithoutSound',\n onClick: () => {\n onSend?.();\n return EmoticonsDropdown.sendDocId(doc.id, false, true);\n },\n verify: () => !!(appImManager.chat.peerId && appImManager.chat.peerId !== rootScope.myId)\n }, {\n icon: 'schedule',\n text: 'Chat.Send.ScheduledMessage',\n onClick: () => appImManager.chat.input.scheduleSending(() => appImManager.chat.input.sendMessageWithDocument(doc)),\n verify: () => !!appImManager.chat.peerId\n }]\n });\n}\n","export default function createVideo(options: {\n pip?: boolean\n} = {}) {\n const video = document.createElement('video');\n if(!options.pip) video.disablePictureInPicture = true;\n video.setAttribute('playsinline', 'true');\n return video;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport rootScope from '../../lib/rootScope';\nimport mediaSizes from '../mediaSizes';\n\nexport type CustomProperty = string;\n\nexport class CustomProperties {\n private cache: {[k in CustomProperty]?: string};\n private computedStyle: CSSStyleDeclaration;\n\n constructor() {\n this.cache = {};\n\n rootScope.addEventListener('theme_change', this.resetCache);\n mediaSizes.addEventListener('resize', this.resetCache);\n }\n\n protected resetCache = () => {\n this.computedStyle = undefined;\n const cache = this.cache;\n this.cache = {};\n\n for(const i in cache) {\n this.getProperty(i);\n }\n };\n\n public getProperty(name: CustomProperty) {\n let value = this.cache[name];\n if(value) {\n return value;\n }\n\n if(!this.computedStyle) {\n this.computedStyle = window.getComputedStyle(document.documentElement);\n }\n\n value = this.computedStyle.getPropertyValue('--' + name).trim();\n return this.cache[name] = value;\n }\n\n public getPropertyAsSize(name: CustomProperty) {\n const value = this.getProperty(name);\n let size: number;\n\n if(value[value.length - 1] === '%') {\n\n } else if(value.indexOf('rem')) {\n size = +value.replace('rem', '') * 16;\n } else {\n size = +value.replace('px', '');\n }\n\n return size;\n }\n}\n\nconst customProperties = new CustomProperties();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.customProperties = customProperties);\nexport default customProperties;\n","export default function simulateEvent(elem: EventTarget, name: string) {\n const event = new Event(name, {bubbles: true, cancelable: true});\n elem.dispatchEvent(event);\n}\n","import encodeEntities from '../string/encodeEntities';\n\nexport default function documentFragmentToHTML(fragment: DocumentFragment) {\n return Array.from(fragment.childNodes).map((node) => {\n return node.nodeType === node.TEXT_NODE ? encodeEntities(node.textContent) : (node as Element).outerHTML;\n }).join('');\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function findUpAsChild<T extends {parentElement: HTMLElement}>(el: T, parent: HTMLElement): T {\n if(!el) return null;\n if(el.parentElement === parent) return el;\n\n while(el.parentElement) {\n el = el.parentElement as any;\n if(el.parentElement === parent) {\n return el;\n }\n }\n\n return null;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function findUpAttribute(el: any, attribute: string): HTMLElement {\n return el.closest(`[${attribute}]`);\n /* if(el.getAttribute(attribute) !== null) return el; // 03.02.2020\n\n while(el.parentElement) {\n el = el.parentElement;\n if(el.getAttribute(attribute) !== null)\n return el;\n }\n return null; */\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function findUpTag(el: any, tag: string): HTMLElement {\n return el.closest(tag);\n /* if(el.tagName === tag) return el; // 03.02.2020\n\n while(el.parentElement) {\n el = el.parentElement;\n if(el.tagName === tag)\n return el;\n }\n return null; */\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ListenerSetter from '../listenerSetter';\n\nexport function requestFullScreen(element: HTMLElement) {\n if(element.requestFullscreen) {\n element.requestFullscreen();\n // @ts-ignore\n } else if(element.mozRequestFullScreen) {\n // @ts-ignore\n element.mozRequestFullScreen(); // Firefox\n // @ts-ignore\n } else if(element.webkitRequestFullscreen) {\n // @ts-ignore\n element.webkitRequestFullscreen(); // Chrome and Safari\n // @ts-ignore\n } else if(element.msRequestFullscreen) {\n // @ts-ignore\n element.msRequestFullscreen();\n }\n}\n\nexport function cancelFullScreen() {\n // @ts-ignore\n if(document.cancelFullScreen) {\n // @ts-ignore\n document.cancelFullScreen();\n // @ts-ignore\n } else if(document.mozCancelFullScreen) {\n // @ts-ignore\n document.mozCancelFullScreen();\n // @ts-ignore\n } else if(document.webkitCancelFullScreen) {\n // @ts-ignore\n document.webkitCancelFullScreen();\n // @ts-ignore\n } else if(document.msExitFullscreen) {\n // @ts-ignore\n document.msExitFullscreen();\n }\n}\n\nexport function addFullScreenListener(element: HTMLElement, callback: (e: Event) => any, listenerSetter?: ListenerSetter) {\n const addListener = listenerSetter ? listenerSetter.add(element) : element.addEventListener.bind(element);\n 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange'.split(' ').forEach((eventName) => {\n addListener(eventName, callback, false);\n });\n}\n\nexport function getFullScreenElement(): HTMLElement {\n // @ts-ignore\n return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;\n}\n\nexport function isFullScreen() {\n return !!getFullScreenElement();\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport findUpAsChild from './findUpAsChild';\n\nexport default function getCaretPosNew(input: HTMLElement, anchor?: boolean): ReturnType<typeof getCaretPosF> & {selection: Selection} {\n const selection = document.getSelection();\n // let {focusNode: node, focusOffset: offset} = selection;\n const node = selection[anchor ? 'anchorNode' : 'focusNode'];\n const offset = selection[anchor ? 'anchorOffset' : 'focusOffset'];\n if(!findUpAsChild(node, input) && node !== input) {\n return {selection} as any;\n }\n\n return {...getCaretPosF(input, node, offset), selection};\n}\n\nexport function getCaretPosF(input: HTMLElement, node: Node, offset: number) {\n if(node === input) {\n const childNodes = input.childNodes;\n const childNodesLength = childNodes.length;\n if(childNodesLength && offset >= childNodesLength) {\n node = childNodes[childNodesLength - 1];\n offset = (node.textContent || (node as HTMLImageElement).alt || '').length;\n } else {\n node = childNodes[offset];\n offset = 0;\n }\n }\n\n return {node: node as ChildNode, offset};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/zhukov/webogram\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\n * https://github.com/zhukov/webogram/blob/master/LICENSE\n */\n\nimport {MessageEntity} from '../../layer';\nimport BOM from '../string/bom';\n\nexport type MarkdownType = 'bold' | 'italic' | 'underline' | 'strikethrough' | 'monospace' | 'link' | 'mentionName' | 'spoiler'/* | 'customEmoji' */;\nexport type MarkdownTag = {\n match: string,\n entityName: Extract<MessageEntity['_'], 'messageEntityBold' | 'messageEntityUnderline' | 'messageEntityItalic' | 'messageEntityCode' | 'messageEntityStrike' | 'messageEntityTextUrl' | 'messageEntityMentionName' | 'messageEntitySpoiler'/* | 'messageEntityCustomEmoji' */>;\n};\n\n// https://core.telegram.org/bots/api#html-style\nexport const markdownTags: {[type in MarkdownType]: MarkdownTag} = {\n bold: {\n match: '[style*=\"bold\"], [style*=\"font-weight: 700\"], [style*=\"font-weight: 600\"], [style*=\"font-weight:700\"], [style*=\"font-weight:600\"], b, strong',\n entityName: 'messageEntityBold'\n },\n underline: {\n match: '[style*=\"underline\"], u, ins',\n entityName: 'messageEntityUnderline'\n },\n italic: {\n match: '[style*=\"italic\"], i, em',\n entityName: 'messageEntityItalic'\n },\n monospace: {\n match: '[style*=\"monospace\"], [face*=\"monospace\"], pre',\n entityName: 'messageEntityCode'\n },\n strikethrough: {\n match: '[style*=\"line-through\"], [style*=\"strikethrough\"], strike, del, s',\n entityName: 'messageEntityStrike'\n },\n link: {\n match: 'A:not(.follow)',\n entityName: 'messageEntityTextUrl'\n },\n mentionName: {\n match: 'A.follow',\n entityName: 'messageEntityMentionName'\n },\n spoiler: {\n match: '[style*=\"spoiler\"]',\n entityName: 'messageEntitySpoiler'\n }\n // customEmoji: {\n // match: '.custom-emoji',\n // entityName: 'messageEntityCustomEmoji'\n // }\n};\n\nconst tabulationMatch = '[style*=\"table-cell\"], th, td';\n\n/* export function getDepth(child: Node, container?: Node) {\n let depth = 0;\n\n do {\n if(child === container) {\n return depth;\n }\n\n ++depth;\n } while((child = child.parentNode) !== null);\n\n return depth;\n} */\n\nconst BLOCK_TAGS = new Set([\n 'DIV',\n 'P',\n 'BR',\n 'LI',\n 'SECTION',\n 'H6',\n 'H5',\n 'H4',\n 'H3',\n 'H2',\n 'H1',\n 'TR',\n 'OL',\n 'UL'\n]);\n\n// const INSERT_NEW_LINE_TAGS = new Set([\n// 'OL',\n// 'UL'\n// ]);\n\nconst BOM_REG_EXP = new RegExp(BOM, 'g');\nexport const SELECTION_SEPARATOR = '\\x01';\n\nfunction checkNodeForEntity(node: Node, value: string, entities: MessageEntity[], offset: {offset: number}) {\n const parentElement = node.parentElement;\n\n // let closestTag: MarkdownTag, closestElementByTag: Element, closestDepth = Infinity;\n for(const type in markdownTags) {\n const tag = markdownTags[type as MarkdownType];\n const closest: HTMLElement = parentElement.closest(tag.match + ', [contenteditable=\"true\"]');\n if(closest?.getAttribute('contenteditable') !== null) {\n /* const depth = getDepth(closest, parentElement.closest('[contenteditable]'));\n if(closestDepth > depth) {\n closestDepth = depth;\n closestTag = tag;\n closestElementByTag = closest;\n } */\n continue;\n }\n\n if(tag.entityName === 'messageEntityTextUrl') {\n entities.push({\n _: tag.entityName,\n url: (closest as HTMLAnchorElement).href,\n offset: offset.offset,\n length: value.length\n });\n } else if(tag.entityName === 'messageEntityMentionName') {\n entities.push({\n _: tag.entityName,\n offset: offset.offset,\n length: value.length,\n user_id: (closest as HTMLElement).dataset.follow.toUserId()\n });\n }/* else if(tag.entityName === 'messageEntityCustomEmoji') {\n entities.push({\n _: tag.entityName,\n document_id: (closest as HTMLElement).dataset.docId,\n offset: offset.offset,\n length: emoji.length\n });\n } */ else {\n entities.push({\n _: tag.entityName,\n offset: offset.offset,\n length: value.length\n });\n }\n }\n}\n\nfunction isLineEmpty(line: string[]) {\n const {length} = line;\n if(!length) {\n return true;\n }\n\n if(line[length - 1] === SELECTION_SEPARATOR && length === SELECTION_SEPARATOR.length) {\n return true;\n }\n\n return false;\n}\n\nexport default function getRichElementValue(\n node: HTMLElement,\n lines: string[],\n line: string[],\n selNode?: Node,\n selOffset?: number,\n entities?: MessageEntity[],\n offset = {offset: 0}\n) {\n if(node.nodeType === node.TEXT_NODE) { // TEXT\n let nodeValue = node.nodeValue;\n // if(nodeValue[0] === BOM) {\n nodeValue = nodeValue.replace(BOM_REG_EXP, '');\n // }\n\n /* const tabulation = node.parentElement?.closest(tabulationMatch + ', [contenteditable]');\n if(tabulation?.getAttribute('contenteditable') === null) {\n nodeValue += ' ';\n // line.push('\\t');\n // ++offset.offset;\n } */\n\n if(nodeValue) {\n if(selNode === node) {\n line.push(nodeValue.substr(0, selOffset) + SELECTION_SEPARATOR + nodeValue.substr(selOffset));\n } else {\n line.push(nodeValue);\n }\n } else if(selNode === node) {\n line.push(SELECTION_SEPARATOR);\n }\n\n if(entities && nodeValue.length && node.parentNode) {\n checkNodeForEntity(node, nodeValue, entities, offset);\n }\n\n offset.offset += nodeValue.length;\n return;\n }\n\n if(node.nodeType !== node.ELEMENT_NODE) { // NON-ELEMENT\n return;\n }\n\n const pushLine = () => {\n lines.push(line.join(''));\n line.length = 0;\n ++offset.offset;\n };\n\n const isSelected = selNode === node;\n const isBlock = BLOCK_TAGS.has(node.tagName);\n if(isBlock && ((line.length && line[line.length - 1].slice(-1) !== '\\n') || node.tagName === 'BR'/* || (BLOCK_TAGS.has(node.tagName) && lines.length) */)) {\n pushLine();\n } else {\n const alt = node.dataset.stickerEmoji || (node as HTMLImageElement).alt;\n const stickerEmoji = node.dataset.stickerEmoji;\n\n if(alt && entities) {\n checkNodeForEntity(node, alt, entities, offset);\n }\n\n if(stickerEmoji && entities) {\n entities.push({\n _: 'messageEntityCustomEmoji',\n document_id: node.dataset.docId,\n offset: offset.offset,\n length: alt.length\n });\n }\n\n if(alt) {\n line.push(alt);\n offset.offset += alt.length;\n }\n }\n\n if(isSelected && !selOffset) {\n line.push(SELECTION_SEPARATOR);\n }\n\n const isTableCell = node.matches(tabulationMatch);\n const wasEntitiesLength = entities?.length;\n const wasLinesLength = lines.length;\n let wasNodeEmpty = true;\n\n let curChild = node.firstChild as HTMLElement;\n while(curChild) {\n getRichElementValue(curChild, lines, line, selNode, selOffset, entities, offset);\n curChild = curChild.nextSibling as any;\n\n if(!isLineEmpty(line)) {\n wasNodeEmpty = false;\n }\n }\n\n // can test on text with list (https://www.who.int/initiatives/sports-and-health)\n if(wasNodeEmpty && node.textContent?.replace(/[\\r\\n]/g, '')) {\n wasNodeEmpty = false;\n }\n\n if(isSelected && selOffset) {\n line.push(SELECTION_SEPARATOR);\n }\n\n if(isTableCell && node.nextSibling && !isLineEmpty(line)) {\n line.push(' ');\n ++offset.offset;\n\n // * combine entities such as url after adding space\n if(wasEntitiesLength !== undefined) {\n for(let i = wasEntitiesLength, length = entities.length; i < length; ++i) {\n ++entities[i].length;\n }\n }\n }\n\n if(isBlock && !wasNodeEmpty) {\n pushLine();\n }\n\n if(!wasNodeEmpty && node.tagName === 'P' && node.nextSibling) {\n lines.push('');\n ++offset.offset;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/zhukov/webogram\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\n * https://github.com/zhukov/webogram/blob/master/LICENSE\n */\n\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport {MessageEntity} from '../../layer';\nimport combineSameEntities from '../../lib/richTextProcessor/combineSameEntities';\nimport sortEntities from '../../lib/richTextProcessor/sortEntities';\nimport getRichElementValue, {SELECTION_SEPARATOR} from './getRichElementValue';\n\nexport function getCaretPos(field: HTMLElement) {\n const sel = window.getSelection();\n let selNode: Node;\n let selOffset: number;\n if(sel?.rangeCount) {\n const range = sel.getRangeAt(0);\n const startOffset = range.startOffset;\n if(\n range.startContainer &&\n range.startContainer == range.endContainer &&\n startOffset == range.endOffset\n ) {\n // * if focused on img, or caret has been set via placeCaretAtEnd\n const possibleChildrenFocusOffset = startOffset - 1;\n const childNodes = field.childNodes;\n if(range.startContainer === field && childNodes[possibleChildrenFocusOffset]) {\n selNode = childNodes[possibleChildrenFocusOffset];\n selOffset = 0;\n\n for(let i = 0; i < range.endOffset; ++i) {\n const node = childNodes[i];\n const value = node.nodeValue || (node as HTMLImageElement).alt;\n\n if(value) {\n selOffset += value.length;\n }\n }\n } else {\n selNode = range.startContainer;\n selOffset = startOffset;\n }\n }\n }\n\n return {node: selNode, offset: selOffset};\n}\n\nexport default function getRichValueWithCaret(\n field: HTMLElement | DocumentFragment,\n withEntities = true,\n withCaret = true\n) {\n const lines: string[] = [];\n const line: string[] = [];\n\n const {node: selNode, offset: selOffset} = !(field instanceof DocumentFragment) && withCaret && getCaretPos(field);\n\n const entities: MessageEntity[] = withEntities ? [] : undefined;\n const offset = {offset: 0};\n if(field instanceof DocumentFragment) {\n let curChild = field.firstChild as HTMLElement;\n while(curChild) {\n getRichElementValue(curChild, lines, line, selNode, selOffset, entities, offset);\n curChild = curChild.nextSibling as any;\n }\n } else {\n getRichElementValue(field, lines, line, selNode, selOffset, entities, offset);\n }\n\n if(line.length) {\n lines.push(line.join(''));\n }\n\n let value = lines.join('\\n');\n const caretPos = value.indexOf(SELECTION_SEPARATOR);\n if(caretPos !== -1) {\n value = value.substr(0, caretPos) + value.substr(caretPos + 1);\n }\n value = value.replace(/\\u00A0/g, ' ');\n\n if(entities?.length) {\n // ! cannot do that here because have the same check before the sending in RichTextProcessor.parseMarkdown\n /* const entity = entities[entities.length - 1];\n const length = value.length;\n const trimmedLength = value.trimRight().length;\n if(length !== trimmedLength) {\n entity.length -= length - trimmedLength;\n } */\n\n combineSameEntities(entities);\n sortEntities(entities);\n }\n\n return {value, entities, caretPos};\n}\n\nMOUNT_CLASS_TO.getRichValueWithCaret = getRichValueWithCaret;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport getVisibleRect from './getVisibleRect';\n\nexport type ViewportSlicePart = {element: HTMLElement, rect: DOMRect, visibleRect: ReturnType<typeof getVisibleRect>}[];\n\nexport default function getViewportSlice({overflowElement, overflowRect, selector, extraSize, elements}: {\n overflowElement: HTMLElement,\n overflowRect?: DOMRectMinified,\n extraSize?: number,\n selector?: string,\n elements?: HTMLElement[]\n}) {\n // const perf = performance.now();\n overflowRect ??= overflowElement.getBoundingClientRect();\n elements ??= Array.from(overflowElement.querySelectorAll<HTMLElement>(selector));\n\n if(extraSize) {\n overflowRect = {\n top: overflowRect.top - extraSize,\n right: overflowRect.right + extraSize,\n bottom: overflowRect.bottom + extraSize,\n left: overflowRect.left - extraSize\n };\n }\n\n const invisibleTop: ViewportSlicePart = [],\n visible: typeof invisibleTop = [],\n invisibleBottom: typeof invisibleTop = [];\n let foundVisible = false;\n for(const element of elements) {\n const rect = element.getBoundingClientRect();\n const visibleRect = getVisibleRect(element, overflowElement, false, rect, overflowRect);\n\n const isVisible = !!visibleRect;\n let array: typeof invisibleTop;\n if(isVisible) {\n foundVisible = true;\n array = visible;\n } else if(foundVisible) {\n array = invisibleBottom;\n } else {\n array = invisibleTop;\n }\n\n array.push({\n element,\n rect,\n visibleRect\n });\n }\n\n // if(extraSize && visible.length) {\n // const maxTop = visible[0].rect.top;\n // const minTop = maxTop - extraSize;\n // const minBottom = visible[visible.length - 1].rect.bottom;\n // const maxBottom = minBottom + extraSize;\n\n // for(let length = invisibleTop.length, i = length - 1; i >= 0; --i) {\n // const element = invisibleTop[i];\n // if(element.rect.top >= minTop) {\n // invisibleTop.splice(i, 1);\n // visible.unshift(element);\n // }\n // }\n\n // for(let i = 0, length = invisibleBottom.length; i < length; ++i) {\n // const element = invisibleBottom[i];\n // if(element.rect.bottom <= maxBottom) {\n // invisibleBottom.splice(i--, 1);\n // --length;\n // visible.push(element);\n // }\n // }\n // }\n\n // console.log('getViewportSlice time:', performance.now() - perf);\n\n return {invisibleTop, visible, invisibleBottom};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport windowSize from '../windowSize';\n\nexport default function getVisibleRect(\n element: HTMLElement,\n overflowElement: HTMLElement,\n lookForSticky?: boolean,\n rect: DOMRectMinified = element.getBoundingClientRect(),\n overflowRect: DOMRectMinified = overflowElement.getBoundingClientRect()\n) {\n let {top: overflowTop, right: overflowRight, bottom: overflowBottom, left: overflowLeft} = overflowRect;\n\n // * respect sticky headers\n if(lookForSticky) {\n const sticky = overflowElement.querySelector('.sticky');\n if(sticky) {\n const stickyRect = sticky.getBoundingClientRect();\n overflowTop = stickyRect.bottom;\n }\n }\n\n if(rect.top >= overflowBottom ||\n rect.bottom <= overflowTop ||\n rect.right <= overflowLeft ||\n rect.left >= overflowRight) {\n return null;\n }\n\n const overflow = {\n top: false,\n right: false,\n bottom: false,\n left: false,\n vertical: 0 as 0 | 1 | 2,\n horizontal: 0 as 0 | 1 | 2\n };\n\n const windowWidth = windowSize.width;\n const windowHeight = windowSize.height;\n\n return {\n rect: {\n top: rect.top < overflowTop && overflowTop !== 0 ? (overflow.top = true, ++overflow.vertical, overflowTop) : rect.top,\n right: rect.right > overflowRight && overflowRight !== windowWidth ? (overflow.right = true, ++overflow.horizontal, overflowRight) : rect.right,\n bottom: rect.bottom > overflowBottom && overflowBottom !== windowHeight ? (overflow.bottom = true, ++overflow.vertical, overflowBottom) : rect.bottom,\n left: rect.left < overflowLeft && overflowLeft !== 0 ? (overflow.left = true, ++overflow.horizontal, overflowLeft) : rect.left\n },\n overflow\n };\n}\n\n(window as any).getVisibleRect = getVisibleRect;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport SwipeHandler, {SwipeHandlerOptions} from '../../components/swipeHandler';\nimport cancelEvent from './cancelEvent';\nimport findUpClassName from './findUpClassName';\nimport isSwipingBackSafari from './isSwipingBackSafari';\n\nexport type SwipeHandlerHorizontalOptions = SwipeHandlerOptions & {\n // xThreshold?: number\n};\n\nexport default function handleHorizontalSwipe(options: SwipeHandlerHorizontalOptions) {\n let cancelY = false;\n return new SwipeHandler({\n ...options,\n verifyTouchTarget: (e) => {\n return !findUpClassName(e.target, 'progress-line') &&\n !isSwipingBackSafari(e as any as TouchEvent) &&\n (options.verifyTouchTarget ? options.verifyTouchTarget(e) : true);\n },\n onSwipe: (xDiff, yDiff, e) => {\n xDiff *= -1;\n yDiff *= -1;\n\n if(!cancelY && Math.abs(yDiff) > 20) {\n return true;\n }\n\n if(Math.abs(xDiff) > Math.abs(yDiff)) {\n cancelEvent(e as any as Event);\n cancelY = true;\n } else if(!cancelY && Math.abs(yDiff) > Math.abs(xDiff)/* || Math.abs(yDiff) > 20 */) {\n return true;\n }\n\n /* if(!cancelY && options.xThreshold !== undefined && xDiff >= options.xThreshold) {\n cancelY = true;\n } */\n\n return options.onSwipe(xDiff, yDiff, e);\n },\n onReset: () => {\n cancelY = false;\n options.onReset && options.onReset();\n },\n cancelEvent: false // cannot use cancelEvent on Safari iOS because scroll will be canceled too\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {cancelContextMenuOpening} from './attachContextMenuListener';\nimport handleHorizontalSwipe, {SwipeHandlerHorizontalOptions} from './handleHorizontalSwipe';\n\nexport default function handleTabSwipe(options: SwipeHandlerHorizontalOptions) {\n return handleHorizontalSwipe({\n ...options,\n onSwipe: (xDiff, yDiff, e) => {\n xDiff *= -1;\n yDiff *= -1;\n\n if(Math.abs(xDiff) > 50) {\n options.onSwipe(xDiff, yDiff, e);\n cancelContextMenuOpening();\n\n return true;\n }\n }\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {markdownTags, MarkdownType} from './getRichElementValue';\n\nexport default function hasMarkupInSelection<T extends MarkdownType>(types: T[], onlyFull?: boolean) {\n const result: Record<T, number> = {} as any;\n types.forEach((tag) => result[tag] = 0);\n const selection = window.getSelection();\n let nodes = -1;\n if(!selection.isCollapsed) {\n const range = selection.getRangeAt(0);\n const commonAncestor = range.commonAncestorContainer;\n const root = commonAncestor.nodeType === commonAncestor.ELEMENT_NODE ?\n commonAncestor as HTMLElement :\n (commonAncestor as ChildNode).parentElement;\n const treeWalker = document.createTreeWalker(\n root.closest('[contenteditable=\"true\"]'),\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,\n {acceptNode: (node) => range.intersectsNode(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT}\n );\n\n nodes = 0;\n let node: Node;\n while(node = treeWalker.nextNode()) {\n ++nodes;\n for(const type of types) {\n const tag = markdownTags[type];\n const matches = (node.nodeType === node.ELEMENT_NODE ? node as HTMLElement : node.parentElement).closest(tag.match);\n if(matches) {\n ++result[type];\n }\n }\n }\n }\n\n const resultBoolean: Record<T, boolean> = {} as any;\n for(const type of types) {\n resultBoolean[type] = result[type] >= (onlyFull ? nodes : 1);\n }\n\n return resultBoolean;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function htmlToDocumentFragment(html: string | DocumentFragment) {\n if(html instanceof DocumentFragment) return html;\n const template = document.createElement('template');\n html = html.trim(); // Never return a text node of whitespace as the result\n template.innerHTML = html;\n return template.content;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function htmlToSpan(html: string | DocumentFragment) {\n const span = document.createElement('span');\n if(typeof(html) === 'string') span.innerHTML = html;\n else span.append(html);\n return span;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/zhukov/webogram\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\n * https://github.com/zhukov/webogram/blob/master/LICENSE\n */\n\n/* export function isInDOM(element: Element, parentNode?: HTMLElement): boolean {\n if(!element) {\n return false;\n }\n\n parentNode = parentNode || document.body;\n if(element === parentNode) {\n return true;\n }\n return isInDOM(element.parentNode as HTMLElement, parentNode);\n} */\nexport default function isInDOM(element: Element): boolean {\n return element?.isConnected;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function isInputEmpty(element: HTMLElement) {\n if(element.isContentEditable || element.tagName !== 'INPUT') {\n /* const value = element.innerText;\n\n return !value.trim() && !serializeNodes(Array.from(element.childNodes)).trim(); */\n // return !getRichValueWithCaret(element, false, false).value.trim();\n return !element.textContent.trim() && !element.querySelector('.emoji, .custom-emoji, .custom-emoji-placeholder');\n } else {\n return !(element as HTMLInputElement).value.trim();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function isSelectionEmpty(selection = window.getSelection()) {\n if(!selection?.rangeCount) {\n return true;\n }\n\n const selectionRange = selection.getRangeAt(0);\n if(selectionRange.collapsed || !selectionRange.START_TO_END) {\n return true;\n }\n\n return false;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport rootScope from '../../lib/rootScope';\nimport {IS_MOBILE, IS_APPLE} from '../../environment/userAgent';\n\nexport default function isSendShortcutPressed(e: KeyboardEvent) {\n if(e.key === 'Enter' && !IS_MOBILE && !e.isComposing) {\n /* if(e.ctrlKey || e.metaKey) {\n this.messageInput.innerHTML += '<br>';\n placeCaretAtEnd(this.message)\n return;\n } */\n\n if(rootScope.settings.sendShortcut === 'enter') {\n if(e.shiftKey || e.ctrlKey || e.metaKey) {\n return;\n }\n\n return true;\n } else {\n const secondaryKey = IS_APPLE ? e.metaKey : e.ctrlKey;\n if(e.shiftKey || (IS_APPLE ? e.ctrlKey : e.metaKey)) {\n return;\n }\n\n if(secondaryKey) {\n return true;\n }\n }\n }\n\n return false;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {IS_MOBILE_SAFARI} from '../../environment/userAgent';\n\nexport default function isSwipingBackSafari(e: TouchEvent | MouseEvent) {\n return IS_MOBILE_SAFARI && e instanceof TouchEvent && e.touches[0].clientX < 30;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/zhukov/webogram\n * Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>\n * https://github.com/zhukov/webogram/blob/master/LICENSE\n */\n\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\n\nexport default function placeCaretAtEnd(el: HTMLElement, ignoreTouchCheck = false, focus = true) {\n if(IS_TOUCH_SUPPORTED && (!ignoreTouchCheck || (document.activeElement.tagName !== 'INPUT' && !(document.activeElement as HTMLElement).isContentEditable))) {\n return;\n }\n\n focus && el.focus();\n if(el instanceof HTMLInputElement) {\n const length = el.value.length;\n el.selectionStart = length;\n el.selectionEnd = length;\n } else {\n const range = document.createRange();\n range.selectNodeContents(el);\n range.collapse(false);\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n }\n}\n\n(window as any).placeCaretAtEnd = placeCaretAtEnd;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport whichChild from './whichChild';\n\nexport default function positionElementByIndex(element: HTMLElement, container: HTMLElement, pos: number, prevPos?: number) {\n if(prevPos === undefined) {\n prevPos = element.parentElement === container ? whichChild(element) : -1;\n }\n\n if(prevPos === pos) {\n return false;\n } else if(prevPos !== -1 && prevPos < pos) { // was higher\n pos += 1;\n }\n\n if(!pos) {\n container.prepend(element);\n } else if(container.childElementCount > pos) {\n container.insertBefore(element, container.children[pos]);\n } else {\n container.append(element);\n }\n\n return true;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function reflowScrollableElement(element: HTMLElement) {\n element.style.display = 'none';\n void element.offsetLeft; // reflow\n element.style.display = '';\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport onMediaLoad from '../onMediaLoad';\n\n// import { getHeavyAnimationPromise } from \"../../hooks/useHeavyAnimationCheck\";\n\nexport const loadedURLs: {[url: string]: boolean} = {};\nconst set = (elem: HTMLElement | HTMLImageElement | SVGImageElement | HTMLVideoElement, url: string) => {\n if(elem instanceof HTMLImageElement || elem instanceof HTMLVideoElement) elem.src = url;\n else if(elem instanceof SVGImageElement) elem.setAttributeNS(null, 'href', url);\n else elem.style.backgroundImage = 'url(' + url + ')';\n};\n\n// проблема функции в том, что она не подходит для ссылок, пригодна только для blob'ов, потому что обычным ссылкам нужен 'load' каждый раз.\nexport default function renderImageFromUrl(\n elem: HTMLElement | HTMLImageElement | SVGImageElement | HTMLVideoElement,\n url: string,\n callback?: () => void,\n useCache = true\n) {\n if(!url) {\n console.error('renderImageFromUrl: no url?', elem, url);\n callback?.();\n return;\n }\n\n const isVideo = elem instanceof HTMLVideoElement;\n if(((loadedURLs[url]/* && false */) && useCache) || isVideo) {\n if(elem) {\n set(elem, url);\n }\n\n if(callback) {\n if(isVideo) {\n onMediaLoad(elem).then(callback);\n } else {\n callback?.();\n }\n // callback && getHeavyAnimationPromise().then(() => callback());\n }\n } else {\n const isImage = elem instanceof HTMLImageElement;\n const loader = isImage ? elem as HTMLImageElement : new Image();\n // const loader = new Image();\n loader.src = url;\n // let perf = performance.now();\n\n const onLoad = () => {\n if(!isImage && elem) {\n set(elem, url);\n }\n\n loadedURLs[url] = true;\n // console.log('onload:', url, performance.now() - perf);\n // TODO: переделать прогрузки аватаров до начала анимации, иначе с этим ожиданием они неприятно появляются\n // callback && getHeavyAnimationPromise().then(() => callback());\n callback?.();\n\n loader.removeEventListener('error', onError);\n };\n\n const onError = (err: ErrorEvent) => {\n console.error('Render image from url failed:', err, url, loader);\n loader.removeEventListener('load', onLoad);\n callback?.();\n };\n\n loader.addEventListener('load', onLoad, {once: true});\n loader.addEventListener('error', onError, {once: true});\n }\n}\n\nexport function renderImageFromUrlPromise(elem: Parameters<typeof renderImageFromUrl>[0], url: string, useCache?: boolean) {\n return new Promise<void>((resolve) => {\n renderImageFromUrl(elem, url, resolve, useCache);\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport sequentialDom from '../sequentialDom';\nimport {renderImageFromUrlPromise} from './renderImageFromUrl';\n\nexport default function renderMediaWithFadeIn(\n container: HTMLElement,\n media: Parameters<typeof renderImageFromUrlPromise>[0],\n url: string,\n needFadeIn: boolean,\n aspecter = container,\n thumbImage?: HTMLElement\n) {\n if(needFadeIn) {\n media.classList.add('fade-in');\n }\n\n const promise = renderImageFromUrlPromise(media, url).then(() => {\n return sequentialDom.mutateElement(container, () => {\n aspecter.append(media);\n\n if(needFadeIn) {\n media.addEventListener('animationend', () => {\n sequentialDom.mutate(() => {\n media.classList.remove('fade-in');\n thumbImage?.remove();\n });\n }, {once: true});\n } else {\n thumbImage?.remove();\n }\n });\n });\n\n // recordPromise(promise, 'renderImageWithFadeIn');\n\n return promise;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function replaceContent(elem: HTMLElement, node: string | Node) {\n if(typeof(node) === 'string') {\n elem.textContent = node;\n return;\n }\n\n // * children.length doesn't count text nodes\n const firstChild = elem.firstChild;\n if(firstChild) {\n if(elem.lastChild === firstChild) {\n firstChild.replaceWith(node);\n } else {\n elem.textContent = '';\n elem.append(node);\n }\n } else {\n elem.append(node);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport clamp from '../number/clamp';\nimport findUpAsChild from './findUpAsChild';\nimport whichChild from './whichChild';\n\nexport default function compareNodes(node1: ChildNode, node1Offset: number, node2: ChildNode, node2Offset: number) {\n let diff: number;\n if(node1 === node2) {\n diff = node1Offset - node2Offset;\n } else if(node1.parentElement === node2.parentElement) {\n diff = whichChild(node1, true) - whichChild(node2, true);\n } else {\n const parents: HTMLElement[] = [];\n let parentElement = node1.parentElement;\n do {\n parents.push(parentElement);\n } while(parentElement = parentElement.parentElement);\n\n parentElement = node2.parentElement;\n do {\n if(parents.includes(parentElement)) {\n break;\n }\n } while(parentElement = parentElement.parentElement);\n\n const commonAncestorContainer = parentElement;\n // const range = document.createRange();\n // range.setStart(node1, 0);\n // range.setEnd(node2, node2.textContent.length);\n // const {commonAncestorContainer} = range;\n node1 = findUpAsChild(node1 as HTMLElement, commonAncestorContainer as HTMLElement);\n node2 = findUpAsChild(node2 as HTMLElement, commonAncestorContainer as HTMLElement);\n diff = whichChild(node1, true) - whichChild(node2, true);\n }\n\n return clamp(diff, -1, 1);\n}\n\n(window as any).compareNodes = compareNodes;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {IS_FIREFOX} from '../../environment/userAgent';\nimport {logger} from '../../lib/logger';\nimport {isCustomFillerNeededBySiblingNode} from '../../lib/richTextProcessor/wrapRichText';\nimport ListenerSetter from '../listenerSetter';\nimport BOM from '../string/bom';\nimport compareNodes from './compareNodes';\nimport getCaretPosNew from './getCaretPosNew';\nimport placeCaretAtEnd from './placeCaretAtEnd';\nimport whichChild from './whichChild';\n\nconst NOT_ONLY_BOMS_REG_EXP = new RegExp(`[^${BOM}]`);\n\nexport const USING_BOMS = false;\n\nexport default class RichInputHandler {\n private static INSTANCE: RichInputHandler;\n\n private listenerSetter: ListenerSetter;\n\n private lastNode: Node;\n private lastOffset: number;\n private savedRanges: WeakMap<HTMLElement, Range>;\n\n private log: ReturnType<typeof logger>;\n\n private inputCaptureCallbacks: Function[];\n\n constructor() {\n this.log = logger('RICH-INPUT');\n this.listenerSetter = new ListenerSetter();\n this.savedRanges = new WeakMap();\n\n this.listenerSetter.add(document)('selectionchange', this.saveSelectionOnChange);\n if(USING_BOMS) {\n this.listenerSetter.add(document)('focusout', this.onFocusOut);\n this.listenerSetter.add(document)('selectionchange', this.onSelectionChange);\n this.listenerSetter.add(document)('beforeinput', this.onBeforeInput);\n this.listenerSetter.add(document)('keydown', this.onKeyDown, {capture: true});\n\n if(IS_FIREFOX) {\n this.inputCaptureCallbacks = [];\n this.listenerSetter.add(document)('input', () => {\n this.inputCaptureCallbacks.forEach((callback) => callback());\n this.inputCaptureCallbacks.length = 0;\n }, {capture: true});\n }\n }\n }\n\n private get input() {\n const selection = document.getSelection();\n const {anchorNode: node} = selection;\n if(!node) return;\n return ((node as HTMLElement).closest ? node as HTMLElement : node.parentElement).closest<HTMLElement>('[contenteditable=\"true\"]');\n }\n\n private saveRangeForElement(element: HTMLElement) {\n if(element && (element.isContentEditable || element.tagName === 'INPUT')) {\n const selection = document.getSelection();\n if(selection.rangeCount) {\n this.savedRanges.set(element as HTMLElement, document.getSelection().getRangeAt(0));\n }\n }\n }\n\n private saveSelectionOnChange = (e: Event) => {\n const element = document.activeElement as HTMLElement; // e.target as HTMLElement;\n this.saveRangeForElement(element);\n };\n\n private onFocusOut = (e: FocusEvent) => {\n this.lastNode = this.lastOffset = undefined;\n };\n\n private findPreviousSmthIndex(input: HTMLElement, node: ChildNode, something?: NodeListOf<Element>) {\n // node = this.getFiller(node);\n // const childNodes = Array.from(node.parentElement.childNodes);\n // fillerIndex = childNodes.indexOf(node);\n // let smthIndex = -1;\n // for(let i = fillerIndex; i >= 0; --i) {\n // const node = childNodes[i];\n // if((node as HTMLElement)?.classList?.contains('input-something')) {\n // smthIndex = i;\n // break;\n // }\n // }\n // return smthIndex;\n\n const elements = Array.from(something ?? input.querySelectorAll('.input-something'));\n const index = elements.findIndex((element) => compareNodes(element, 0, node, 0) >= 0);\n return index === -1 ? elements.length - 1 : Math.max(0, index - 1);\n }\n\n private superMove(\n input: HTMLElement,\n caret: ReturnType<RichInputHandler['getCaretPosN']>,\n toLeft: boolean,\n fromSelectionChange: boolean\n ) {\n const {node, offset, move} = caret;\n const something = input.querySelectorAll('.input-something');\n const smthIndex = this.findPreviousSmthIndex(input, node, something);\n const r = document.createRange();\n r[toLeft ? 'setEnd' : 'setStart'](node, offset);\n\n if(fromSelectionChange) {\n move(toLeft);\n }\n\n const c = this.getCaretPosN();\n if(c.node?.nodeValue === BOM && (!fromSelectionChange || node === this.lastNode)) {\n const idx = this.findPreviousSmthIndex(input, c.node, something);\n\n let moved = !fromSelectionChange;\n\n do {\n const c = this.getCaretPosN();\n const idxidx = this.findPreviousSmthIndex(input, c.node, something);\n r[toLeft ? 'setStart' : 'setEnd'](c.node, c.offset);\n const rangeString = r.toString();\n const onlyBOMs = !NOT_ONLY_BOMS_REG_EXP.test(rangeString);\n this.log('test cursor', rangeString, onlyBOMs, idx, idxidx);\n if(\n onlyBOMs &&\n c.node?.nodeValue === BOM &&\n idxidx === idx &&\n // (idxidx > 1 || c.offset) &&\n // (idxidx < (getFiller(c.node).parentElement.childNodes.length - 2) || c.offset < BOM.length)\n (idxidx || c.offset) &&\n (idxidx < (something.length - 1) || c.offset < BOM.length)\n ) {\n move(toLeft);\n moved = true;\n } else if(!moved) {\n break;\n } else {\n if((!this.getFiller(node as HTMLElement).classList.contains('input-filler-text') && idx !== smthIndex) || c.offset === BOM.length) {\n move(!toLeft);\n }\n\n break;\n }\n } while(true);\n }\n }\n\n private onSelectionChange = (e: Event) => {\n const {input} = this;\n if(!input) {\n this.setSelectionClassName(document.getSelection());\n return;\n }\n\n // return;\n\n // this.log('selectionchange', document.getSelection(), document.getSelection().rangeCount && document.getSelection().getRangeAt(0), getCaretPosN());\n // let {node, offset} = getCaretPos(this.messageInput);\n\n let caret = this.getCaretPosN();\n do {\n const {node, offset, selection, move} = caret;\n\n const nodeValue = node?.nodeValue;\n // if(!nodeValue?.includes(BOM)) {\n if(nodeValue !== BOM || !this.lastNode) {\n break;\n }\n\n // node = getFiller(node);\n\n // const childIndex = whichChild(getFiller(node), true);\n // let toLeft: boolean;\n // // if(node === lastNode) toLeft = lastOffset >= offset;\n // if(node === lastNode) toLeft = lastOffset > offset;\n // else {\n // // toLeft = whichChild(getFiller(lastNode)) > childIndex;\n // toLeft = (lastNode.nodeValue === BOM ? whichChild(getFiller(lastNode), true) : whichChild(findUpAsChild(lastNode as any, getFiller(node).parentElement), true)) > childIndex;\n // }\n\n const toLeft = compareNodes(node, offset, this.lastNode as ChildNode, this.lastOffset) < 0;\n\n // const childNodes = Array.from(node.parentElement.childNodes);\n // if(toLeft) {\n // for(let i = childIndex; i >= 0; --i) {\n // const sibling = childNodes[i];\n // const {textContent} = sibling;\n // for()\n // }\n // }\n\n // {\n // if(toLeft === undefined) {\n // return;\n // }\n\n // const selection = window.getSelection();\n // selection.modify(selection.isCollapsed ? 'move' : 'extend', toLeft ? 'backward' : 'forward', 'character');\n // return;\n // }\n\n // const parent = getFiller(node);\n if(toLeft !== undefined) {\n // let newNode = toLeft ? parent.previousSibling : parent.nextSibling;\n if(selection.isCollapsed) {\n this.superMove(input, caret, toLeft, true);\n\n // if(offset === BOM.length) {\n // newNode = toLeft ? newNode.nextSibling.nextSibling : parent.previousSibling.previousSibling;\n // }\n\n // setCaretAt(newNode);\n } else {\n selection.modify(selection.isCollapsed ? 'move' : 'extend', toLeft ? 'backward' : 'forward', 'character');\n // const range = selection.getRangeAt(0);\n\n // if(toLeft) {\n // newNode = parent.previousSibling.previousSibling.firstChild;\n // const value = newNode.nodeValue;\n // range.setStart(newNode, value?.length);\n // } else {\n // newNode = parent.nextSibling.nextSibling.firstChild;\n // range.setEnd(newNode, 0);\n // }\n }\n }\n\n this.log('selectionchange',\n node,\n offset,\n this.lastNode,\n this.lastOffset,\n node === this.lastNode,\n whichChild(this.getFiller(node)),\n whichChild(this.getFiller(this.lastNode)),\n toLeft,\n selection,\n document.getSelection(),\n document.getSelection().getRangeAt(0),\n node?.parentNode,\n this.lastNode?.parentNode\n );\n\n caret = this.getCaretPosN();\n this.lastNode = node;\n this.lastOffset = offset;\n\n break;\n\n // if(findPreviousSmthIndex(caret.node) !== smthIndex) {\n // break;\n // }\n } while(true);\n\n this.lastNode = this.lastOffset = undefined;\n\n // if(offset === BOM.length) {\n // setCaretAt(parent);\n // } else {\n // setCaretAt(parent.nextSibling);\n // }\n\n this.setSelectionClassName(caret.selection, input);\n };\n\n public restoreSavedRange(input: HTMLElement) {\n const range = this.getSavedRange(input);\n if(!range) {\n return false;\n }\n\n const selection = window.getSelection();\n selection.removeAllRanges();\n selection.addRange(range);\n\n return true;\n }\n\n public getSavedRange(input: HTMLElement) {\n return this.savedRanges.get(input);\n }\n\n public makeFocused(input: HTMLElement) {\n if(document.activeElement !== input && !this.restoreSavedRange(input)) {\n placeCaretAtEnd(input, false, false);\n }\n }\n\n private fixInsertedLineBreaks(input: HTMLElement) {\n input.querySelectorAll('br').forEach((br) => {\n br.classList.add('br-not-br');\n });\n }\n\n private fixBuggedCaret() {\n const selection = document.getSelection();\n const range = selection.getRangeAt(0);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n\n public onBeforeInput = (e: Pick<InputEvent, 'inputType'>) => {\n const {input, log} = this;\n if(!input) {\n return;\n }\n\n const addInputCallback = this.addInputCallback.bind(this, input);\n\n const caretPos = this.getCaretPosN();\n let {node, offset, selection, move} = caretPos;\n log('beforeinput', e, node, offset, selection, caretPos);\n this.lastNode = this.lastOffset = undefined;\n\n if(e.inputType.startsWith('delete')) { // delete current BOM\n addInputCallback(() => {\n this.processEmptiedFillers(input);\n this.removeExtraBOMs(input);\n this.fixInsertedLineBreaks(input);\n });\n\n if(node?.nodeValue === BOM && selection.isCollapsed && e.inputType.includes('deleteContent')) {\n const toLeft = e.inputType.includes('Backward');\n const moveFirst = (offset === BOM.length && toLeft) || (!offset && !toLeft);\n this.superMove(input, caretPos, toLeft, moveFirst);\n // if((offset === BOM.length && toLeft) || (!offset && !toLeft)) {\n // move(toLeft);\n // }\n\n // addInputCallback(() => {\n // removePossibleBOMSiblingsByNode(getFiller(node));\n // });\n\n // if(node.parentNode.childNodes.length === 1) {\n // (node.parentNode as HTMLElement).remove();\n // move(e.inputType.includes('Backward') ? false : true);\n // } else {\n // move(e.inputType.includes('Backward') ? true : false);\n // addInputCallback(() => {\n // move(e.inputType.includes('Backward') ? false : true);\n // });\n // }\n\n // for(let i = 0, length = BOM.length + (direction === 'backward' ? offset : BOM.length - offset); i < length; ++i) {\n // selection.modify('extend', direction, 'character');\n // }\n\n // selection.modify('extend', direction, 'character');\n // selection.modify('extend', direction, 'character');\n\n // selection.deleteFromDocument();\n // e.preventDefault();\n } else {\n // const filler = getFiller(node);\n // if(filler?.classList?.contains('input-filler-text')) {\n // const {previousSibling, nextSibling} = filler;\n // addInputCallback(() => {\n // if(!filler.isConnected) {\n // removePossibleBOMSiblings(previousSibling, nextSibling);\n // }\n // // removeExtraBOMs();\n // // processEmptiedFillers();\n // });\n // }\n // addInputCallback(() => {\n // this.fixInsertedLineBreaks(input);\n // });\n }\n } else if(e.inputType.startsWith('insert')) { // clear current BOM\n if((node as HTMLElement)?.classList?.contains('input-something')/* || (node.textContent === BOM && offset === BOM.length) */) {\n node = node.previousSibling.firstChild;\n const range = selection.getRangeAt(0);\n range.setStart(node, 0);\n range.setEnd(node, 0);\n range.collapse(true);\n // selection.modify('move', 'backward', 'character');\n\n const c = this.getCaretPosN();\n node = c.node;\n selection = c.selection;\n offset = c.offset;\n }\n if(node && node.textContent === BOM && offset === BOM.length) {\n // const range = selection.getRangeAt(0);\n // range.setStart(node, 0);\n // range.setEnd(node, 0);\n // range.collapse(true);\n selection.modify('move', 'backward', 'character');\n\n const c = this.getCaretPosN();\n node = c.node;\n selection = c.selection;\n offset = c.offset;\n }\n // if(node && node.textContent === BOM && offset === 0) {\n // selection.modify('move', 'forward', 'character');\n // offset = BOM.length;\n // }\n\n if(e.inputType === 'insertLineBreak' || true) {\n // const appendix = 'X';\n // const textNode = document.createTextNode(appendix);\n // if(node.parentElement !== this.messageInput) node.parentElement.after(textNode);\n // else node.after(textNode);\n // selection.modify('move', 'forward', 'character');\n // selection.modify('move', 'forward', 'character');\n // addInputCallback(() => {\n // textNode.remove();\n // });\n\n /* if(node?.nodeValue === BOM) */ {\n // const parent = node.parentElement;\n // parent.contentEditable = 'false';\n // addInputCallback(() => {\n // parent.contentEditable = 'inherit';\n // });\n // node.parentElement.remove();\n\n // const textNode = document.createTextNode(appendix);\n // if(node.parentElement !== this.messageInput) node.parentElement.after(textNode);\n // else node.after(textNode);\n // // selection.modify('move', 'forward', 'character');\n // // selection.modify('move', 'forward', 'character');\n // addInputCallback(() => {\n // textNode.remove();\n // });\n\n // fix case when focused somehow on span instead of text node\n if(node && node.nodeType === node.ELEMENT_NODE) {\n node = node.firstChild;\n log.warn('fixing focus on span');\n }\n\n const isBOM = node?.nodeValue === BOM;\n log('inserting line break', isBOM, node, `\"${node?.nodeValue}\"`, node?.parentElement ? Array.from(node.parentElement.childNodes).slice() : []);\n if(isBOM) {\n // (node as ChildNode).replaceWith(this.messageInput.querySelector('.lol'));\n\n const parentElement = node.parentElement;\n parentElement.classList.replace('input-filler', 'input-filler-text');\n const childNodesLength = parentElement.childNodes.length;\n addInputCallback(() => {\n const newChildNodesLength = parentElement.childNodes.length;\n if(newChildNodesLength > 1/* && newChildNodesLength !== childNodesLength */) {\n log('inserting line break, remove');\n node = Array.from(parentElement.childNodes).find((node) => node.nodeValue === BOM);\n (parentElement as any).t = node;\n // node?.remove();\n\n // const n = parentElement.firstChild;\n // const range = selection.getRangeAt(0);\n // range.setStart(n, n.nodeValue.length);\n // range.setEnd(n, n.nodeValue.length);\n } else if(node.nodeValue !== BOM) {\n log('inserting line break, deleteData');\n (node as CharacterData).deleteData(node.nodeValue.indexOf(BOM), BOM.length);\n // node = document.createTextNode(BOM);\n }\n\n this.fixInsertedLineBreaks(input);\n // (parentElement as any).t = node;\n // node.remove();\n });\n // addInputCallback(() => {\n // node.parentElement.classList.replace('input-filler', 'input-filler3');\n // const s = document.createElement('span');\n // s.style.display = 'none';\n // node.replaceWith(s);\n // s.prepend(node);\n // });\n } else if(e.inputType === 'insertLineBreak') {\n addInputCallback(() => {\n this.fixInsertedLineBreaks(input);\n });\n // const range = selection.getRangeAt(0);\n // this.messageInput.querySelectorAll<HTMLElement>('.input-something').forEach((el) => {\n // el.contentEditable = 'inherit';\n // });\n\n // addInputCallback(() => {\n // this.messageInput.querySelectorAll<HTMLElement>('.input-something').forEach((el) => {\n // el.contentEditable = 'false';\n // });\n\n // selection.removeAllRanges();\n // selection.addRange(range);\n // }, false);\n }/* else if(node &&\n node.nodeType === node.TEXT_NODE &&\n node.nodeValue.length === offset) {\n\n } */\n\n // if(e.inputType === 'insertLineBreak') {\n // e.preventDefault();\n // document.execCommand('insertHTML', false, '<span class=\"lol\">\\n</span>');\n\n // this.messageInputField.simulateInputEvent();\n // }\n\n // node.parentElement.replaceWith(node);\n // selection.removeAllRanges();\n // const range = new Range();\n // range.setStart(node, 0);\n // range.setEnd(node, node.nodeValue.length);\n // selection.addRange(range);\n // node.parentElement.classList.remove('input-filler');\n // node.parentElement\n }\n\n // document.execCommand('insertHTML', false, '\\n');\n // e.preventDefault();\n // (node as CharacterData).deleteData(node.nodeValue.indexOf(BOM), BOM.length);\n // if(node?.nodeValue === BOM) {\n // addInputCallback(() => {\n // node.remove();\n // });\n // }\n // this.messageInputField.simulateInputEvent();\n\n // this.messageInput.querySelectorAll<HTMLElement>('.input-something').forEach((el) => {\n // el.contentEditable = 'inherit';\n // });\n // addInputCallback(() => {\n // this.messageInput.querySelectorAll<HTMLElement>('.input-something').forEach((el) => {\n // el.contentEditable = 'false';\n // });\n // });\n return;\n }\n\n if(node?.nodeValue === BOM) {\n // node.nodeValue = ''; // ! will move cursor forward\n // addInputCallback(() => {\n // (node as CharacterData).deleteData(node.nodeValue.indexOf(BOM), BOM.length);\n // });\n\n if(e.inputType === 'insertLineBreak') {\n if(offset === BOM.length) {\n selection.modify('move', 'backward', 'character');\n }\n\n // if(offset !== BOM.length) {\n // selection.modify('move', 'forward', 'character');\n // }\n\n addInputCallback(() => {\n node.remove();\n // (node as CharacterData).deleteData(node.nodeValue.indexOf(BOM), BOM.length);\n // selection.modify('move', 'forward', 'character');\n\n setTimeout(() => {\n selection.modify('move', 'forward', 'character');\n }, 0);\n });\n }\n\n // node.parentElement.replaceWith(node);\n\n // node.parentElement.replaceWith(node);\n if(e.inputType === 'insertLineBreak') {\n // const previousParentSibling = node.parentNode.previousSibling;\n // addInputCallback(() => {\n // if(previousParentSibling.nextSibling.nodeValue === '\\n') {\n // previousParentSibling.nextSibling.remove();\n\n // setTimeout(() => {\n // // selection.modify('move', 'forward', 'character');\n // // selection.modify('move', 'forward', 'character');\n // }, 0);\n // } else {\n // previousParentSibling.nextSibling.nodeValue = previousParentSibling.nextSibling.nodeValue.replace('\\n\\n', '\\n');\n // }\n // });\n } else {\n // if(node.parentElement !== this.messageInput) {\n // node.parentElement.replaceWith(node);\n // }\n\n // setTimeout(() => {\n // this.log(JSON.stringify(node.parentElement.innerHTML));\n // node.nodeValue = node.nodeValue.replace(BOM, '');\n // // (node as CharacterData).deleteData(node.nodeValue.indexOf(BOM), BOM.length);\n // this.log(JSON.stringify(node.parentElement.innerHTML));\n // }, 1000);\n\n addInputCallback(() => {\n (node as CharacterData).deleteData(node.nodeValue.indexOf(BOM), BOM.length);\n if(!node.nodeValue) {\n node.remove();\n }\n\n // selection.modify('move', 'forward', 'character');\n });\n }\n\n if(selection.isCollapsed && false) {\n node.parentElement.replaceWith(node);\n // const textNode = document.createTextNode(BOM);\n // (node.parentNode as any as ChildNode).after(textNode);\n // setCaretAt(textNode.nextSibling);\n // selection.modify('move', 'forward', 'character');\n node.remove();\n // (node as CharacterData).deleteData(node.nodeValue.indexOf(BOM), BOM.length);\n // selection.modify('move', 'forward', 'character');\n // selection.collapseToEnd();\n\n // addInputCallback(() => {\n // (textNode as CharacterData).deleteData(textNode.nodeValue.indexOf(BOM), BOM.length);\n // node.parentElement.remove();\n // });\n }\n } else if(e.inputType === 'insertLineBreak' &&\n node &&\n node.nodeType === node.TEXT_NODE &&\n node.nodeValue.length === offset) {\n log('inserting line break');\n // const appendix = '\\x01';\n\n input.querySelectorAll<HTMLElement>('.input-something').forEach((el) => {\n el.contentEditable = 'inherit';\n });\n addInputCallback(() => {\n input.querySelectorAll<HTMLElement>('.input-something').forEach((el) => {\n el.contentEditable = 'false';\n });\n });\n\n // const textNode = document.createTextNode(appendix);\n // if(node.parentElement !== this.messageInput) node.parentElement.after(textNode);\n // else node.after(textNode);\n // // selection.modify('move', 'forward', 'character');\n // addInputCallback(() => {\n // textNode.remove();\n // });\n\n // const offset = node.nodeValue.length;\n // (node as CharacterData).insertData(offset, appendix);\n // addInputCallback(() => {\n // selection.modify('move', 'forward', 'character');\n // (node as CharacterData).deleteData(node.nodeValue.indexOf(appendix), appendix.length);\n // if(!node.nodeValue) {\n // node.remove();\n // }\n // });\n }\n } else if(e.inputType === 'historyUndo') { // have to remove extra BOMs\n addInputCallback(() => {\n this.processFilledFillers(input);\n this.processEmptiedFillers(input);\n this.removeExtraBOMs(input);\n this.removeEmptyTextNodes(input);\n\n // ! lol what, caret will be at the wrong position, have to set it to the same\n this.fixBuggedCaret();\n\n // lol\n // this.messageInput.querySelectorAll('.has-text').forEach((el) => {\n // if(el.textContent === BOM) {\n // el.firstElementChild.replaceWith(el.firstElementChild.firstChild);\n // el.classList.replace('input-filler3', 'input-filler');\n // }\n // });\n });\n } else if(e.inputType === 'historyRedo') {\n // if(node?.nodeValue === BOM && offset === BOM.length) {\n // selection.modify('move', 'backward', 'character');\n // }\n\n addInputCallback(() => {\n this.processFilledFillers(input);\n this.processEmptiedFillers(input);\n\n // fix contenteditable attribute\n input.querySelectorAll<HTMLElement>('.input-something:not([contenteditable])').forEach((el) => {\n el.contentEditable = 'false';\n });\n\n this.removeExtraBOMs(input);\n\n // ! lol what, caret will be at the wrong position, have to set it to the same\n this.fixBuggedCaret();\n });\n }\n };\n\n private onKeyDown = (e: KeyboardEvent) => {\n const key = e.key;\n\n // // have to ignore line up and down\n if(key === 'ArrowDown' || key === 'ArrowUp') {\n this.lastNode = this.lastOffset = undefined;\n } else {\n const {node, offset} = this.getCaretPosN();\n this.lastNode = node/* getFiller(node) */, this.lastOffset = offset;\n if(this.lastNode === this.input) {\n this.lastNode = this.lastOffset = undefined;\n }\n }\n\n this.log('keydown', this.lastNode, this.lastNode?.parentNode, this.lastOffset, this.getCaretPosN(), e);\n };\n\n private addInputCallback(input: HTMLElement, callback: () => void, capture = true) {\n const newCallback = () => {\n this.log('input modify callback');\n callback();\n };\n\n if(capture && IS_FIREFOX) this.inputCaptureCallbacks.push(newCallback);\n else this.listenerSetter.add(input)('input', newCallback, {once: true, capture});\n }\n\n public removeExtraBOMs(input: HTMLElement) {\n const c = (sibling: ChildNode) => {\n return (sibling as HTMLElement)?.classList?.contains('input-something');\n };\n\n input.querySelectorAll('.input-filler').forEach((el) => {\n const {previousSibling, nextSibling} = el;\n let needed = false;\n\n // if(!(previousSibling as HTMLElement)?.classList?.contains('input-filler') && isCustomFillerNeededBySiblingNode(previousSibling)) {\n if(!(nextSibling as HTMLElement)?.classList?.contains('input-filler') && isCustomFillerNeededBySiblingNode(nextSibling)) {\n needed = c(previousSibling) || c(nextSibling);\n }\n\n if(!needed) {\n this.log.warn('removing empty bom node', el);\n el.remove();\n }\n });\n }\n\n private getFiller(node: Node) {\n return node && node.nodeType === node.TEXT_NODE && node.parentElement !== this.input ? node.parentElement : node as HTMLElement;\n }\n\n private getCaretPosN() {\n const ret = getCaretPosNew(this.input);\n // const {node} = ret;\n // if((node as HTMLElement)?.classList?.contains('input-something')) {\n // ret.node = node.previousSibling;\n // ret.offset = ret.node.textContent.length;\n // }\n\n return {...ret, move: this.move.bind(this, ret.selection)};\n }\n\n private removeEmptyTextNodes(input: HTMLElement) {\n const {log} = this;\n // let i = -1;\n // remove empty text nodes\n const treeWalker = document.createTreeWalker(\n input,\n NodeFilter.SHOW_TEXT,\n {acceptNode: (node) => node.parentElement === input && !node.nodeValue/* && !++i */ ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT}\n );\n\n let textNode: Text;\n while(textNode = treeWalker.nextNode() as Text) {\n log.warn('removing empty text node', textNode);\n textNode.remove();\n }\n }\n\n private removePossibleBOMSiblings(previousSibling: ChildNode, nextSibling: ChildNode) {\n [previousSibling, nextSibling].forEach((sibling) => {\n if((sibling as HTMLElement)?.classList?.contains('input-filler')) {\n sibling.remove();\n }\n });\n }\n\n private removePossibleBOMSiblingsByNode(node: ChildNode) {\n const {previousSibling, nextSibling} = node;\n this.removePossibleBOMSiblings(previousSibling, nextSibling);\n };\n\n private processEmptiedFillers(input: HTMLElement) {\n input.querySelectorAll<HTMLElement>('.input-filler-text').forEach((el) => {\n this.removeExtraBOMs(el);\n\n let cleanSiblings = true;\n if(!el.textContent) {\n el.classList.replace('input-filler-text', 'input-filler');\n\n const textNode = Array.from(el.childNodes).find((node) => node.nodeType === node.TEXT_NODE);\n if(textNode) {\n (textNode as CharacterData).insertData(0, BOM);\n } else if(((el as any).t as ChildNode)?.nodeValue) {\n el.append((el as any).t);\n } else {\n el.append(document.createTextNode(BOM));\n }\n } else if(!NOT_ONLY_BOMS_REG_EXP.test(el.textContent) && !el.querySelector('.input-something')) {\n el.classList.replace('input-filler-text', 'input-filler');\n } else {\n cleanSiblings = false;\n }\n\n if(cleanSiblings) {\n this.removePossibleBOMSiblingsByNode(el);\n }\n });\n }\n\n private processFilledFillers(input: HTMLElement) {\n // remove the BOM when changing to text\n input.querySelectorAll('.input-filler').forEach((el) => {\n if(el.textContent !== BOM) {\n el.classList.replace('input-filler', 'input-filler-text');\n const t = (el as any).t as ChildNode;\n const bomNode = Array.from(el.childNodes).find((node) => node.nodeType === node.TEXT_NODE && node.nodeValue.includes(BOM));\n if(bomNode && !t?.nodeValue) {\n const idx = bomNode.nodeValue.indexOf(BOM);\n if(idx !== -1) {\n (bomNode as CharacterData).deleteData(idx, BOM.length);\n }\n }\n\n // t?.remove();\n }\n });\n }\n\n private setSelectionClassName(selection: Selection, input?: HTMLElement) {\n // Array.from(this.messageInput.querySelectorAll('.selection')).forEach((element) => {\n // element.classList.remove('selection');\n // });\n\n if(selection.rangeCount) {\n const range = selection.getRangeAt(0);\n\n if(input) {\n Array.from(input.querySelectorAll('.input-selectable')).forEach((element) => {\n element.classList.toggle('selection', !range.collapsed && range.intersectsNode(element));\n });\n } else {\n Array.from(document.querySelectorAll('.input-selectable.selection')).forEach((element) => element.classList.remove('selection'));\n }\n }\n }\n\n private move(selection: Selection, left: boolean) {\n const {focusNode: focusNodeBefore, focusOffset: focusOffsetBefore} = selection;\n selection.modify('extend', left ? 'backward' : 'forward', 'character');\n // if(offset === nodeValue.length) {\n // selection.modify('extend', !left ? 'backward' : 'forward', 'character');\n // }\n if(left) selection.collapseToStart();\n else selection.collapseToEnd();\n const {focusNode: focusNodeAfter, focusOffset: focusOffsetAfter} = selection;\n this.log(\n 'moving cursor',\n left,\n focusNodeBefore,\n focusNodeBefore.nodeType === focusNodeBefore.ELEMENT_NODE ? focusNodeBefore : focusNodeBefore.parentElement,\n focusOffsetBefore,\n focusNodeAfter,\n focusNodeAfter.nodeType === focusNodeAfter.ELEMENT_NODE ? focusNodeAfter : focusNodeAfter.parentElement,\n focusOffsetAfter\n );\n }\n\n public prepareApplyingMarkdown() {\n const {input} = this;\n\n // do not wrap fillers into spans\n const fillers = input.querySelectorAll<HTMLElement>('.input-filler');\n // fillers.forEach((el) => {\n // el.contentEditable = 'false';\n // });\n\n const smths = input.querySelectorAll<HTMLElement>('.input-something');\n smths.forEach((el) => {\n el.contentEditable = 'inherit';\n });\n\n return () => {\n fillers.forEach((el) => {\n el.contentEditable = 'inherit';\n });\n\n smths.forEach((el) => {\n el.contentEditable = 'false';\n });\n\n this.removeExtraBOMs(input);\n };\n }\n\n public static getInstance() {\n return this.INSTANCE ??= new RichInputHandler();\n }\n}\n","import rootScope from '../../lib/rootScope';\nimport liteMode from '../liteMode';\n\nexport default function shake(element: HTMLElement) {\n if(!liteMode.isAvailable('animations')) {\n return;\n }\n\n const keyframes: Keyframe[] = [\n {transform: 'translateX(0)'},\n {transform: 'translateX(.25rem)'},\n {transform: 'translateX(-.25rem)'},\n {transform: 'translateX(0)'}\n ];\n\n element.animate([...keyframes, ...keyframes, ...keyframes], {\n duration: 300,\n iterations: 1,\n easing: 'ease-in-out'\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {ScrollableBase} from '../../components/scrollable';\nimport SwipeHandler from '../../components/swipeHandler';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport rootScope from '../../lib/rootScope';\nimport liteMode from '../liteMode';\nimport {Middleware} from '../middleware';\nimport clamp from '../number/clamp';\nimport safeAssign from '../object/safeAssign';\nimport pause from '../schedulers/pause';\nimport cancelEvent from './cancelEvent';\nimport {attachClickEvent} from './clickEvent';\nimport findUpAsChild from './findUpAsChild';\nimport positionElementByIndex from './positionElementByIndex';\nimport whichChild from './whichChild';\n\nexport default class Sortable {\n private element: HTMLElement;\n private elementRect: DOMRect;\n private containerRect: DOMRect;\n private scrollableRect: DOMRect;\n private minY: number;\n private maxY: number;\n private siblings: HTMLElement[];\n private swipeHandler: SwipeHandler;\n private startScrollPos: number;\n private addScrollPos: number;\n\n private list: HTMLElement;\n private middleware: Middleware;\n private onSort: (prevIdx: number, newIdx: number) => void;\n private scrollable: ScrollableBase;\n\n constructor(options: {\n list: HTMLElement,\n middleware: Middleware,\n onSort: Sortable['onSort'],\n scrollable?: Sortable['scrollable']\n }) {\n safeAssign(this, options);\n\n this.swipeHandler = new SwipeHandler({\n element: this.list,\n onSwipe: this.onSwipe,\n verifyTouchTarget: this.verifyTouchTarget,\n onStart: this.onStart,\n onReset: this.onReset,\n setCursorTo: document.body,\n middleware: this.middleware,\n withDelay: true\n });\n }\n\n private onSwipe = (xDiff: number, yDiff: number) => {\n yDiff = clamp(yDiff, this.minY, this.maxY);\n this.element.style.transform = `translateY(${yDiff}px)`;\n const count = Math.round(Math.abs(yDiff) / this.elementRect.height);\n const lastSiblings = this.siblings;\n this.siblings = [];\n const property = yDiff < 0 ? 'previousElementSibling' : 'nextElementSibling';\n let sibling = this.element[property] as HTMLElement;\n for(let i = 0; i < count; ++i) {\n if(this.getSortableTarget(sibling)) {\n this.siblings.push(sibling);\n sibling = sibling[property] as HTMLElement;\n } else {\n break;\n }\n }\n\n (lastSiblings || []).forEach((sibling) => {\n if(!this.siblings.includes(sibling)) {\n sibling.style.transform = '';\n }\n });\n\n this.siblings.forEach((sibling) => {\n const y = this.elementRect.height * (yDiff < 0 ? 1 : -1);\n sibling.style.transform = `translateY(${y}px)`;\n });\n\n if(this.scrollableRect) {\n const diff = yDiff;\n const toEnd = diff > 0;\n const elementEndPos = toEnd ? this.elementRect.bottom : this.elementRect.top;\n const clientY = elementEndPos + diff - this.addScrollPos;\n // console.log(clientY, this.scrollableRect.top, elementEndPos, diff, this.addScrollPos, toEnd);\n let change = 2;\n if((clientY + (toEnd ? 0 : this.elementRect.height)) >= this.scrollableRect.bottom/* && diff < this.maxY */) {\n\n } else if((clientY - (toEnd ? this.elementRect.height : 0)) <= this.scrollableRect.top/* && diff > this.minY */) {\n change *= -1;\n } else {\n change = undefined;\n }\n\n if(change !== undefined) {\n this.scrollable.container[this.scrollable.scrollProperty] += change;\n }\n }\n };\n\n private verifyTouchTarget = (e: {target: EventTarget}) => {\n if(this.list.classList.contains('is-reordering')) {\n return false;\n }\n\n this.element = this.getSortableTarget(e.target as HTMLElement);\n return !!this.element/* && pause(150).then(() => true) */;\n };\n\n private onScroll = () => {\n const scrollPos = this.scrollable.container[this.scrollable.scrollProperty];\n const diff = this.addScrollPos = scrollPos - this.startScrollPos;\n const isVertical = this.scrollable.scrollProperty === 'scrollTop';\n this.swipeHandler.add(isVertical ? 0 : diff, isVertical ? diff : 0);\n };\n\n private onStart = () => {\n this.list.classList.add('is-reordering');\n this.element.classList.add('is-dragging', 'no-transition');\n this.swipeHandler.setCursor('grabbing');\n this.elementRect = this.element.getBoundingClientRect();\n this.containerRect = this.list.getBoundingClientRect();\n\n this.minY = this.containerRect.top - this.elementRect.top;\n this.maxY = this.containerRect.bottom - this.elementRect.bottom;\n this.addScrollPos = 0;\n\n if(this.scrollable) {\n this.startScrollPos = this.scrollable.container[this.scrollable.scrollProperty];\n this.scrollableRect = this.scrollable.container.getBoundingClientRect();\n this.scrollable.container.addEventListener('scroll', this.onScroll);\n }\n };\n\n private onReset = async() => {\n const length = this.siblings.length;\n const move = length && length * (this.siblings[0].previousElementSibling === this.element ? 1 : -1);\n const idx = whichChild(this.element);\n const newIdx = idx + move;\n\n this.element.classList.remove('no-transition');\n this.element.style.transform = move ? `translateY(${move * this.elementRect.height}px)` : '';\n this.swipeHandler.setCursor('');\n\n if(this.scrollable) {\n this.scrollable.container.removeEventListener('scroll', this.onScroll);\n }\n\n if(!IS_TOUCH_SUPPORTED) {\n attachClickEvent(document.body, cancelEvent, {capture: true, once: true});\n }\n\n if(liteMode.isAvailable('animations')) {\n await pause(250);\n }\n\n this.list.classList.remove('is-reordering');\n this.element.classList.remove('is-dragging');\n positionElementByIndex(this.element, this.list, newIdx, idx);\n [this.element, ...this.siblings].forEach((element) => {\n element.style.transform = '';\n });\n\n this.element =\n this.siblings =\n this.elementRect =\n this.containerRect =\n this.minY =\n this.maxY =\n this.startScrollPos =\n this.addScrollPos =\n undefined;\n\n // cancelClick = true;\n\n if(!move) {\n return;\n }\n\n this.onSort(idx, newIdx);\n };\n\n private getSortableTarget(target: HTMLElement) {\n if(!target) {\n return;\n }\n\n let child = findUpAsChild(target as HTMLElement, this.list);\n if(child && child.classList.contains('cant-sort')) {\n child = undefined;\n }\n\n return child;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function toggleDisability(elements: HTMLElement[], disable: boolean): () => void {\n if(disable) {\n elements.forEach((el) => el.setAttribute('disabled', 'true'));\n } else {\n elements.forEach((el) => el.removeAttribute('disabled'));\n }\n\n return () => toggleDisability(elements, !disable);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function whichChild(elem: Node, countNonElements?: boolean) {\n if(!elem.parentNode) {\n return -1;\n }\n\n if(countNonElements) {\n return Array.from(elem.parentNode.childNodes).indexOf(elem as ChildNode);\n }\n\n let i = 0;\n // @ts-ignore\n while((elem = elem.previousElementSibling) !== null) ++i;\n return i;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {attachClickEvent} from './dom/clickEvent';\nimport findUpAsChild from './dom/findUpAsChild';\nimport EventListenerBase from './eventListenerBase';\nimport ListenerSetter from './listenerSetter';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport safeAssign from './object/safeAssign';\nimport appNavigationController, {NavigationItem} from '../components/appNavigationController';\nimport findUpClassName from './dom/findUpClassName';\nimport rootScope from '../lib/rootScope';\nimport liteMode from './liteMode';\n\nconst KEEP_OPEN = false;\nconst TOGGLE_TIMEOUT = 200;\nconst ANIMATION_DURATION = 200;\n\nexport type IgnoreMouseOutType = 'click' | 'menu' | 'popup';\ntype DropdownHoverTimeoutType = 'toggle' | 'done';\n\nexport default class DropdownHover extends EventListenerBase<{\n open: () => Promise<any> | void,\n openAfterLayout: () => void,\n opened: () => any,\n close: () => any,\n closed: () => any\n}> {\n protected element: HTMLElement;\n protected forceClose: boolean;\n protected inited: boolean;\n protected ignoreMouseOut: Set<IgnoreMouseOutType>;\n protected ignoreButtons: Set<HTMLElement>;\n protected navigationItem: NavigationItem;\n protected ignoreOutClickClassName: string;\n protected timeouts: {[type in DropdownHoverTimeoutType]?: number};\n protected detachClickEvent: () => void;\n\n constructor(options: {\n element: DropdownHover['element'],\n ignoreOutClickClassName?: string\n }) {\n super(false);\n safeAssign(this, options);\n this.forceClose = false;\n this.inited = false;\n this.ignoreMouseOut = new Set();\n this.ignoreButtons = new Set();\n this.timeouts = {};\n }\n\n public attachButtonListener(\n button: HTMLElement,\n listenerSetter: ListenerSetter\n ) {\n let firstTime = true;\n if(IS_TOUCH_SUPPORTED) {\n attachClickEvent(button, () => {\n if(firstTime) {\n firstTime = false;\n this.toggle(true);\n } else {\n this.toggle();\n }\n }, {listenerSetter});\n } else {\n listenerSetter.add(button)('mouseover', (e) => {\n if(firstTime) {\n listenerSetter.add(button)('mouseout', (e) => {\n this.clearTimeout('toggle');\n this.onMouseOut(e);\n });\n firstTime = false;\n }\n\n this.setTimeout('toggle', () => {\n this.toggle(true);\n }, TOGGLE_TIMEOUT);\n });\n\n attachClickEvent(button, () => {\n const type: IgnoreMouseOutType = 'click';\n const ignore = !this.ignoreMouseOut.has(type);\n\n if(ignore && !this.ignoreMouseOut.size) {\n this.ignoreButtons.add(button);\n setTimeout(() => {\n this.detachClickEvent = attachClickEvent(window, this.onClickOut, {capture: true});\n }, 0);\n }\n\n this.setIgnoreMouseOut(type, ignore);\n this.toggle(ignore);\n }, {listenerSetter});\n }\n }\n\n protected onClickOut = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if(\n !findUpAsChild(target, this.element) &&\n !Array.from(this.ignoreButtons).some((button) => findUpAsChild(target, button) || target === button) &&\n this.ignoreMouseOut.size <= 1 &&\n (!this.ignoreOutClickClassName || !findUpClassName(target, this.ignoreOutClickClassName))\n ) {\n this.toggle(false);\n }\n };\n\n protected onMouseOut = (e: MouseEvent) => {\n if(KEEP_OPEN || !this.isActive()) return;\n this.clearTimeout('toggle');\n\n if(this.ignoreMouseOut.size) {\n return;\n }\n\n const toElement = (e as any).toElement as HTMLElement;\n if(toElement && findUpAsChild(toElement, this.element)) {\n return;\n }\n\n this.setTimeout('toggle', () => {\n this.toggle(false);\n }, TOGGLE_TIMEOUT);\n };\n\n protected clearTimeout(type: DropdownHoverTimeoutType) {\n if(this.timeouts[type] !== undefined) {\n clearTimeout(this.timeouts[type]);\n delete this.timeouts[type];\n }\n }\n\n protected setTimeout(type: DropdownHoverTimeoutType, cb: () => void, timeout: number) {\n this.clearTimeout(type);\n this.timeouts[type] = window.setTimeout(() => {\n this.clearTimeout(type);\n cb();\n }, timeout);\n }\n\n public init() {\n if(!IS_TOUCH_SUPPORTED) {\n this.element.onmouseout = this.onMouseOut;\n this.element.onmouseover = (e) => {\n if(this.forceClose) {\n return;\n }\n\n // console.log('onmouseover element');\n this.clearTimeout('toggle');\n };\n }\n }\n\n public toggle = async(enable?: boolean) => {\n // if(!this.element) return;\n const willBeActive = (!!this.element.style.display && enable === undefined) || enable;\n if(this.init) {\n if(willBeActive) {\n this.init();\n this.init = null;\n } else {\n return;\n }\n }\n\n if(willBeActive === this.isActive()) {\n return;\n }\n\n const delay = IS_TOUCH_SUPPORTED || !liteMode.isAvailable('animations') ? 0 : ANIMATION_DURATION;\n if((this.element.style.display && enable === undefined) || enable) {\n const res = this.dispatchResultableEvent('open');\n await Promise.all(res);\n\n this.element.style.display = '';\n void this.element.offsetLeft; // reflow\n this.element.classList.add('active');\n\n this.dispatchEvent('openAfterLayout');\n\n appNavigationController.pushItem(this.navigationItem = {\n type: 'dropdown',\n onPop: () => {\n this.toggle(false);\n }\n });\n\n this.clearTimeout('toggle');\n this.setTimeout('done', () => {\n this.forceClose = false;\n this.dispatchEvent('opened');\n }, delay);\n\n // ! can't use together with resizeObserver\n /* if(isTouchSupported) {\n const height = this.element.scrollHeight + appImManager.chat.input.inputContainer.scrollHeight - 10;\n console.log('[ESG]: toggle: enable height', height);\n appImManager.chat.bubbles.scrollable.scrollTop += height;\n } */\n\n /* if(touchSupport) {\n this.restoreScroll();\n } */\n } else {\n this.dispatchEvent('close');\n this.ignoreMouseOut.clear();\n this.ignoreButtons.clear();\n\n this.element.classList.remove('active');\n\n appNavigationController.removeItem(this.navigationItem);\n this.detachClickEvent?.();\n this.detachClickEvent = undefined;\n\n this.clearTimeout('toggle');\n this.setTimeout('done', () => {\n this.element.style.display = 'none';\n this.forceClose = false;\n this.dispatchEvent('closed');\n }, delay);\n\n /* if(isTouchSupported) {\n const scrollHeight = this.container.scrollHeight;\n if(scrollHeight) {\n const height = this.container.scrollHeight + appImManager.chat.input.inputContainer.scrollHeight - 10;\n appImManager.chat.bubbles.scrollable.scrollTop -= height;\n }\n } */\n\n /* if(touchSupport) {\n this.restoreScroll();\n } */\n }\n\n // animationIntersector.checkAnimations(false, EMOTICONSSTICKERGROUP);\n };\n\n public isActive() {\n return this.element.classList.contains('active');\n }\n\n public setIgnoreMouseOut(type: IgnoreMouseOutType, ignore: boolean) {\n ignore ? this.ignoreMouseOut.add(type) : this.ignoreMouseOut.delete(type);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// * Jolly Cobra's fastSmoothScroll slightly patched\n\nimport {dispatchHeavyAnimationEvent} from '../hooks/useHeavyAnimationCheck';\nimport {fastRafPromise} from './schedulers';\nimport {animateSingle, cancelAnimationByKey} from './animation';\nimport rootScope from '../lib/rootScope';\nimport isInDOM from './dom/isInDOM';\nimport liteMode from './liteMode';\n\nconst MIN_JS_DURATION = 250;\nconst MAX_JS_DURATION = 600;\nconst LONG_TRANSITION_MAX_DISTANCE = 1500;\nconst SHORT_TRANSITION_MAX_DISTANCE = 500;\n\nexport enum FocusDirection {\n Up,\n Down,\n Static,\n};\n\nexport type ScrollGetNormalSizeCallback = (options: {rect: DOMRect}) => number;\nexport type ScrollGetElementPositionCallback = (options: {elementRect: DOMRect, containerRect: DOMRect, elementPosition: number}) => number;\nexport type ScrollStartCallbackDimensions = {\n scrollSize: number,\n scrollPosition: number,\n distanceToEnd: number,\n path: number,\n duration: number,\n containerRect: DOMRect,\n elementRect: DOMRect,\n getProgress: () => number\n};\n\nexport type ScrollOptions = {\n container: HTMLElement,\n element: HTMLElement,\n position: ScrollLogicalPosition,\n margin?: number,\n maxDistance?: number,\n forceDirection?: FocusDirection,\n forceDuration?: number,\n axis?: 'x' | 'y',\n getNormalSize?: ScrollGetNormalSizeCallback,\n getElementPosition?: ScrollGetElementPositionCallback,\n fallbackToElementStartWhenCentering?: HTMLElement,\n startCallback?: (dimensions: ScrollStartCallbackDimensions) => void,\n transitionFunction?: (value: number) => number\n};\n\nexport default function fastSmoothScroll(options: ScrollOptions) {\n options.margin ??= 0;\n options.maxDistance ??= LONG_TRANSITION_MAX_DISTANCE;\n options.axis ??= 'y';\n // return;\n\n if(!liteMode.isAvailable('animations') || options.forceDuration === 0) {\n options.forceDirection = FocusDirection.Static;\n }\n\n if(options.forceDirection === FocusDirection.Static) {\n options.forceDuration = 0;\n return scrollWithJs(options);\n /* return Promise.resolve();\n\n element.scrollIntoView({ block: position });\n\n cancelAnimationByKey(container);\n return Promise.resolve(); */\n }\n\n const promise = fastRafPromise().then(() => scrollWithJs(options));\n\n return options.axis === 'y' ? dispatchHeavyAnimationEvent(promise) : promise;\n}\n\nfunction scrollWithJs(options: ScrollOptions): Promise<void> {\n const {element, container, getNormalSize, getElementPosition, transitionFunction, axis, margin, position, forceDirection, maxDistance, forceDuration} = options;\n if(!isInDOM(element)) {\n cancelAnimationByKey(container);\n return Promise.resolve();\n }\n\n const rectStartKey = axis === 'y' ? 'top' : 'left';\n const rectEndKey = axis === 'y' ? 'bottom' : 'right';\n const sizeKey = axis === 'y' ? 'height' : 'width';\n const scrollSizeKey = axis === 'y' ? 'scrollHeight' : 'scrollWidth';\n const elementScrollSizeKey = axis === 'y' ? 'scrollHeight' : 'offsetWidth'; // can use offsetWidth for X, since it's almost same as scrollWidth\n const scrollPositionKey = axis === 'y' ? 'scrollTop' : 'scrollLeft';\n\n // const { offsetTop: elementTop, offsetHeight: elementHeight } = element;\n const elementRect = element.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect ? container.getBoundingClientRect() : document.body.getBoundingClientRect();\n\n // const transformable = container.firstElementChild as HTMLElement;\n\n const possibleElementPosition = elementRect[rectStartKey] - containerRect[rectStartKey];\n const elementPosition = getElementPosition ? getElementPosition({elementRect, containerRect, elementPosition: possibleElementPosition}) : possibleElementPosition;\n const elementSize = element[elementScrollSizeKey]; // margin is exclusive in DOMRect\n\n const containerSize = getNormalSize ? getNormalSize({rect: containerRect}) : containerRect[sizeKey];\n\n let scrollPosition = container[scrollPositionKey];\n const scrollSize = container[scrollSizeKey];\n /* const elementPosition = element.offsetTop;\n const elementSize = element.offsetHeight;\n\n const scrollPosition = container[scrollPositionKey];\n const scrollSize = container[scrollSizeKey];\n const containerSize = container.offsetHeight; */\n\n let path!: number;\n\n switch(position) {\n case 'start':\n path = elementPosition - margin;\n break;\n case 'end':\n path = elementRect[rectEndKey] /* + (elementSize - elementRect[sizeKey]) */ - containerRect[rectEndKey] + margin;\n break;\n // 'nearest' is not supported yet\n case 'nearest':\n case 'center':\n if(elementSize < containerSize) {\n path = (elementPosition + elementSize / 2) - (containerSize / 2);\n } else {\n if(options.fallbackToElementStartWhenCentering && options.fallbackToElementStartWhenCentering !== element) {\n options.element = options.fallbackToElementStartWhenCentering;\n options.position = 'start';\n return scrollWithJs(options);\n }\n\n path = elementPosition - margin;\n }\n\n break;\n }\n /* switch (position) {\n case 'start':\n path = (elementPosition - margin) - scrollPosition;\n break;\n case 'end':\n path = (elementPosition + elementSize + margin) - (scrollPosition + containerSize);\n break;\n // 'nearest' is not supported yet\n case 'nearest':\n case 'center':\n path = elementSize < containerSize\n ? (elementPosition + elementSize / 2) - (scrollPosition + containerSize / 2)\n : (elementPosition - margin) - scrollPosition;\n break;\n } */\n\n if(Math.abs(path - (margin || 0)) < 1) {\n cancelAnimationByKey(container);\n return Promise.resolve();\n }\n\n if(axis === 'y') {\n if(forceDirection === undefined) {\n if(path > maxDistance) {\n scrollPosition = container.scrollTop += path - maxDistance;\n path = maxDistance;\n } else if(path < -maxDistance) {\n scrollPosition = container.scrollTop += path + maxDistance;\n path = -maxDistance;\n }\n }/* else if(forceDirection === FocusDirection.Up) { // * not tested yet\n container.scrollTop = offsetTop + container.scrollTop + maxDistance;\n } else if(forceDirection === FocusDirection.Down) { // * not tested yet\n container.scrollTop = Math.max(0, offsetTop + container.scrollTop - maxDistance);\n } */\n }\n\n // console.log('scrollWithJs: will scroll path:', path, element);\n\n /* let existsTransform = 0;\n const currentTransform = transformable.style.transform;\n if(currentTransform) {\n existsTransform = parseInt(currentTransform.match(/\\((.+?), (.+?), .+\\)/)[2]);\n //path += existsTransform;\n } */\n\n if(path < 0) {\n const remainingPath = -scrollPosition;\n path = Math.max(path, remainingPath);\n } else if(path > 0) {\n const remainingPath = scrollSize - (scrollPosition + containerSize);\n path = Math.min(path, remainingPath);\n }\n\n const target = container[scrollPositionKey] + path;\n const absPath = Math.abs(path);\n const duration = forceDuration ?? (\n MIN_JS_DURATION + (absPath / LONG_TRANSITION_MAX_DISTANCE) * (MAX_JS_DURATION - MIN_JS_DURATION)\n );\n const startAt = Date.now();\n\n /* transformable.classList.add('no-transition');\n\n const tickTransform = () => {\n const t = duration ? Math.min((Date.now() - startAt) / duration, 1) : 1;\n const currentPath = path * transition(t);\n\n transformable.style.transform = `translate3d(0, ${-currentPath}px, 0)`;\n container.dataset.translate = '' + -currentPath;\n\n const willContinue = t < 1;\n if(!willContinue) {\n fastRaf(() => {\n delete container.dataset.transform;\n container.dataset.transform = '';\n transformable.style.transform = '';\n void transformable.offsetLeft; // reflow\n transformable.classList.remove('no-transition');\n void transformable.offsetLeft; // reflow\n container[scrollPositionKey] = Math.round(target);\n });\n }\n\n return willContinue;\n };\n\n return animateSingle(tickTransform, container); */\n\n /* return new Promise((resolve) => {\n fastRaf(() => {\n transformable.style.transform = '';\n transformable.style.transition = '';\n\n setTimeout(resolve, duration);\n });\n });\n\n const transformableHeight = transformable.scrollHeight;\n //transformable.style.minHeight = `${transformableHeight}px`;\n */\n\n const transition = transitionFunction ?? (absPath < SHORT_TRANSITION_MAX_DISTANCE ? shortTransition : longTransition);\n const getProgress = () => duration ? Math.min((Date.now() - startAt) / duration, 1) : 1;\n const tick = () => {\n const t = getProgress();\n const value = transition(t);\n const currentPath = path * (1 - value);\n container[scrollPositionKey] = Math.round(target - currentPath);\n\n return t < 1;\n };\n\n if(!duration || !path) {\n cancelAnimationByKey(container);\n tick();\n return Promise.resolve();\n }\n\n /* return new Promise((resolve) => {\n setTimeout(resolve, duration);\n }).then(() => {\n transformable.classList.add('no-transition');\n void transformable.offsetLeft; // reflow\n transformable.style.transform = '';\n transformable.style.transition = '';\n void transformable.offsetLeft; // reflow\n transformable.classList.remove('no-transition');\n void transformable.offsetLeft; // reflow\n fastRaf(() => {\n\n container[scrollPositionKey] = Math.round(target);\n //transformable.style.minHeight = ``;\n });\n\n }); */\n\n if(options.startCallback) {\n const distanceToEnd = scrollSize - Math.round(target + container[axis === 'y' ? 'offsetHeight' : 'offsetWidth']);\n options.startCallback({\n scrollSize,\n scrollPosition,\n distanceToEnd,\n path,\n duration,\n containerRect,\n elementRect,\n getProgress\n });\n }\n\n return animateSingle(tick, container);\n}\n\nfunction longTransition(t: number) {\n return 1 - ((1 - t) ** 5);\n}\n\nfunction shortTransition(t: number) {\n return 1 - ((1 - t) ** 3.5);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {InputFileLocation, InputStickerSet, InputWebFileLocation} from '../layer';\nimport type {DownloadOptions} from '../lib/mtproto/apiFileManager';\n\nconst FILENAME_JOINER = '_';\n\nexport function getFileNameByLocation(location: InputFileLocation | InputWebFileLocation, options?: Partial<{\n fileName: string,\n downloadId: string\n}>) {\n const fileName = '';// (options?.fileName || '').split('.');\n const ext = fileName[fileName.length - 1] || '';\n\n let str: string;\n switch(location._) {\n case 'inputPhotoFileLocation': {\n str = ['photo', fileName[0], location.id, location.thumb_size].filter(Boolean).join(FILENAME_JOINER);\n break;\n }\n\n case 'inputDocumentFileLocation': {\n str = ['document', fileName[0], location.id, location.thumb_size].filter(Boolean).join(FILENAME_JOINER);\n break;\n }\n\n case 'inputPeerPhotoFileLocation':\n str = ['peerPhoto', location.photo_id, location.pFlags.big ? 'big' : 'small'].join(FILENAME_JOINER);\n break;\n\n case 'inputStickerSetThumb': {\n const id = (location.stickerset as InputStickerSet.inputStickerSetID).id ||\n (location.stickerset as InputStickerSet.inputStickerSetShortName).short_name ||\n (location.stickerset as InputStickerSet.inputStickerSetDice).emoticon ||\n location.stickerset._;\n str = ['stickerSetThumb', id, location.thumb_version].join(FILENAME_JOINER);\n break;\n }\n\n case 'inputFileLocation': {\n str = [location.volume_id, location.local_id].join(FILENAME_JOINER);\n break;\n }\n\n case 'inputWebFileLocation': {\n str = ['webFile', location.url].join(FILENAME_JOINER);\n break;\n }\n\n default: {\n console.error('Unrecognized location:', location);\n str = '';\n break;\n }\n }\n\n return str + (options?.downloadId ? '_download' : '') + (ext ? '.' + ext : ext);\n}\n\nexport type FileURLType = 'photo' | 'thumb' | 'document' | 'stream' | 'download';\nexport function getFileURL(type: FileURLType, options: DownloadOptions) {\n // console.log('getFileURL', location);\n // const perf = performance.now();\n const encoded = encodeURIComponent(JSON.stringify(options));\n // console.log('getFileURL encode:', performance.now() - perf, encoded);\n\n return /* '/' + */type + '/' + encoded;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {Message, MessageAction} from '../layer';\nimport type {MyMessage} from '../lib/appManagers/appMessagesManager';\nimport forEachReverse from './array/forEachReverse';\n\nexport default function filterChatPhotosMessages(value: {\n count: number;\n next_rate: number;\n offset_id_offset: number;\n history: MyMessage[];\n}) {\n forEachReverse(value.history, (message, idx, arr) => {\n if(!((message as Message.messageService).action as MessageAction.messageActionChatEditPhoto).photo) {\n arr.splice(idx, 1);\n if(value.count !== undefined) {\n --value.count;\n }\n }\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {i18n, LangPackKey} from '../lib/langPack';\n\nexport default function formatBytes(bytes: number, decimals: number | 'auto' = 'auto') {\n if(bytes === 0) return i18n('FileSize.B', [0]);\n\n const strictDecimals = decimals === 'auto';\n\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n const _decimals = decimals === 'auto' ? Math.max(0, i - 1) : decimals;\n\n const dm = Math.max(0, _decimals);\n const sizes: LangPackKey[] = ['FileSize.B', 'FileSize.KB', 'FileSize.MB', 'FileSize.GB'];\n\n const fixed = (bytes / Math.pow(k, i)).toFixed(dm);\n return i18n(sizes[i], [strictDecimals ? fixed : parseFloat(fixed)]);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport I18n, {i18n, join, LangPackKey} from '../lib/langPack';\nimport formatDuration, {DurationType} from './formatDuration';\n\nconst CALL_DURATION_LANG_KEYS: {[type in DurationType]: LangPackKey} = {\n s: 'Seconds',\n m: 'Minutes',\n h: 'Hours',\n d: 'Days',\n w: 'Weeks',\n mm: 'Months',\n y: 'Years'\n};\nexport default function formatCallDuration(duration: number, plain?: boolean) {\n const a = formatDuration(duration, 2);\n if(plain) {\n const strings = a.map((d) => I18n.format(CALL_DURATION_LANG_KEYS[d.type], true, [d.duration]));\n return join(strings, false, plain);\n }\n\n const elements = a.map((d) => i18n(CALL_DURATION_LANG_KEYS[d.type], [d.duration]));\n\n const fragment = document.createElement('span');\n fragment.append(...join(elements, false));\n\n return fragment;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport type DurationType = 's' | 'm' | 'h' | 'd' | 'w' | 'mm' | 'y';\nexport default function formatDuration(duration: number, showLast = 2) {\n if(!duration) {\n duration = 1;\n }\n\n const d: {duration: number, type: DurationType}[] = [];\n const p = [\n {m: 1, t: 's'},\n {m: 60, t: 'm'},\n {m: 60, t: 'h'},\n {m: 24, t: 'd'},\n {m: 7, t: 'w'}\n ] as Array<{m?: number, t: DurationType}>\n const s = 1;\n let t = s;\n p.forEach((o, idx) => {\n t = Math.round(t * o.m);\n\n if(duration < t) {\n return;\n }\n\n let dd = duration / t;\n if(idx !== (p.length - 1)) {\n const modulus = p[idx === (p.length - 1) ? idx : idx + 1].m;\n dd %= modulus;\n }\n\n d.push({\n duration: dd | 0,\n type: o.t\n });\n });\n\n const out = d.slice(-showLast).reverse();\n for(let i = out.length - 1; i >= 0; --i) {\n if(out[i].duration === 0) {\n out.splice(i, 1);\n }\n }\n\n return out;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {HelpCountry, HelpCountryCode} from '../layer';\nimport I18n from '../lib/langPack';\n\nlet sortedCountries: HelpCountry[];\ntype PrefixCountry = {country: HelpCountry, code: HelpCountryCode};\nconst prefixes: Map<string, PrefixCountry> = new Map();\nlet maxPrefixLength = 0;\nconst setPrefix = (country: HelpCountry, code: HelpCountryCode, prefix: string = '') => {\n prefix = code.country_code + prefix;\n /* if(prefixes.has(prefix)) {\n console.error('asdasdasd', prefixes.get(prefix), country, code);\n } */\n maxPrefixLength = Math.max(maxPrefixLength, prefix.length);\n prefixes.set(prefix, {country, code});\n};\n\nexport function formatPhoneNumber(originalStr: string): {\n formatted: string,\n country: HelpCountry,\n code: HelpCountryCode,\n leftPattern: string\n} {\n originalStr = originalStr || '';\n\n if(!prefixes.size) {\n I18n.countriesList.forEach((country) => {\n country.country_codes.forEach((code) => {\n if(code.prefixes) {\n code.prefixes.forEach((prefix) => {\n setPrefix(country, code, prefix);\n });\n } else {\n setPrefix(country, code);\n }\n });\n });\n }\n\n // return {formatted: originalStr, country: undefined as any, leftPattern: ''};\n let str = originalStr.replace(/\\D/g, '');\n const phoneCode = str.slice(0, maxPrefixLength);\n\n // //console.log('str', str, phoneCode);\n // if(!sortedCountries) {\n // sortedCountries = I18n.countriesList.slice().sort((a, b) => b.country_codes[0].country_code.length - a.country_codes[0].country_code.length);\n // }\n\n // let country = sortedCountries.find((c) => {\n // return c.country_codes.find((c) => phoneCode.indexOf(c.replace(/\\D/g, '')) === 0);\n // });\n\n let prefixCountry: PrefixCountry;\n for(let i = phoneCode.length - 1; i >= 0; --i) { // lookup for country by prefix\n prefixCountry = prefixes.get(phoneCode.slice(0, i + 1));\n if(prefixCountry) {\n break;\n }\n }\n\n if(!prefixCountry) {\n return {\n formatted: str,\n country: undefined,\n code: undefined,\n leftPattern: ''\n };\n }\n\n // country = /* PhoneCodesMain[country.phoneCode] || */country;\n const country = prefixCountry.country;\n\n const patterns = prefixCountry.code.patterns || [];\n const searchForPattern = str.slice(prefixCountry.code.country_code.length); // splice country code\n let pattern = '', mostMatchedPatternMatches = 0, mostMatchedPattern = '';\n for(let i = patterns.length - 1; i >= 0; --i) {\n pattern = patterns[i];\n\n const _pattern = pattern.replace(/ /g, '');\n let patternMatches = 0;\n for(let k = 0, length = Math.min(searchForPattern.length, _pattern.length); k < length; ++k) {\n if(searchForPattern[k] === _pattern[k]) {\n patternMatches += 1.01;\n } else if(_pattern[k] === 'X') {\n ++patternMatches;\n } else {\n patternMatches = 0;\n break;\n }\n }\n\n if(patternMatches > mostMatchedPatternMatches) {\n mostMatchedPatternMatches = patternMatches;\n mostMatchedPattern = pattern;\n }\n }\n\n pattern = mostMatchedPattern || pattern;\n pattern = pattern.replace(/\\d/g, 'X');\n\n pattern = prefixCountry.code.country_code + ' ' + pattern;\n // let pattern = country.pattern || country.phoneCode;\n pattern.split('').forEach((symbol, idx) => {\n if(symbol === ' ' && str[idx] !== ' ' && str.length > idx) {\n str = str.slice(0, idx) + ' ' + str.slice(idx);\n }\n });\n\n /* if(country.pattern) {\n str = str.slice(0, country.pattern.length);\n } */\n\n let leftPattern = pattern && pattern.length > str.length ? pattern.slice(str.length) : '';\n if(leftPattern) {\n /* const length = str.length;\n leftPattern = leftPattern.split('').map((_, idx) => (length + idx).toString().slice(-1)).join(''); */\n leftPattern = leftPattern.replace(/X/g, '');\n // leftPattern = leftPattern.replace(/X/g, '0');\n }\n\n return {formatted: str, country, code: prefixCountry.code, leftPattern};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {RLottieColor} from '../lib/rlottie/rlottiePlayer';\n\nexport type FramesCacheMap = Map<number, Uint8ClampedArray>;\nexport type FramesCacheMapNew = Map<number, HTMLCanvasElement | ImageBitmap>;\nexport type FramesCacheMapURLs = Map<number, string>;\nexport type FramesCacheItem = {\n frames: FramesCacheMap,\n framesNew: FramesCacheMapNew,\n framesURLs: FramesCacheMapURLs,\n clearCache: () => void,\n counter: number\n};\n\nexport class FramesCache {\n private cache: Map<string, FramesCacheItem>;\n\n constructor() {\n this.cache = new Map();\n }\n\n public static createCache(): FramesCacheItem {\n const cache: FramesCacheItem = {\n frames: new Map(),\n framesNew: new Map(),\n framesURLs: new Map(),\n clearCache: () => {\n cache.framesNew.forEach((value) => {\n (value as ImageBitmap).close?.();\n });\n\n cache.frames.clear();\n cache.framesNew.clear();\n cache.framesURLs.clear();\n },\n counter: 0\n };\n\n return cache;\n }\n\n public getCache(name: string) {\n let cache = this.cache.get(name);\n if(!cache) {\n this.cache.set(name, cache = FramesCache.createCache());\n } else {\n // console.warn('[RLottieCache] cache will be reused', cache);\n }\n\n ++cache.counter;\n return cache;\n }\n\n public releaseCache(name: string) {\n const cache = this.cache.get(name);\n if(cache && !--cache.counter) {\n this.cache.delete(name);\n // console.warn('[RLottieCache] released cache', cache);\n }\n }\n\n public getCacheCounter(name: string) {\n const cache = this.cache.get(name);\n return cache?.counter;\n }\n\n public generateName(name: string, width: number, height: number, color: RLottieColor, toneIndex: number) {\n return [\n name,\n width,\n height,\n // color ? rgbaToHexa(color) : ''\n color ? 'colored' : '',\n toneIndex || ''\n ].filter(Boolean).join('-');\n }\n}\n\nconst framesCache = new FramesCache();\n\nexport default framesCache;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// generate a path's arc data parameter\n\nimport {MOUNT_CLASS_TO} from '../config/debug';\n\n// http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands\nfunction arcParameter(rx: number, ry: number, xAxisRotation: number, largeArcFlag: number, sweepFlag: number, x: number, y: number) {\n return [rx, ',', ry, ' ',\n xAxisRotation, ' ',\n largeArcFlag, ',',\n sweepFlag, ' ',\n x, ',', y].join('');\n}\n\nexport default function generatePathData(x: number, y: number, width: number, height: number, tl: number, tr: number, br: number, bl: number) {\n const data: string[] = [];\n\n // start point in top-middle of the rectangle\n data.push('M' + (x + width / 2) + ',' + y);\n\n // next we go to the right\n data.push('H' + (x + width - tr));\n\n if(tr > 0) {\n // now we draw the arc in the top-right corner\n data.push('A' + arcParameter(tr, tr, 0, 0, 1, (x + width), (y + tr)));\n }\n\n // next we go down\n data.push('V' + (y + height - br));\n\n if(br > 0) {\n // now we draw the arc in the lower-right corner\n data.push('A' + arcParameter(br, br, 0, 0, 1, (x + width - br), (y + height)));\n }\n\n // now we go to the left\n data.push('H' + (x + bl));\n\n if(bl > 0) {\n // now we draw the arc in the lower-left corner\n data.push('A' + arcParameter(bl, bl, 0, 0, 1, (x + 0), (y + height - bl)));\n }\n\n // next we go up\n data.push('V' + (y + tl));\n\n if(tl > 0) {\n // now we draw the arc in the top-left corner\n data.push('A' + arcParameter(tl, tl, 0, 0, 1, (x + tl), (y + 0)));\n }\n\n // and we close the path\n data.push('Z');\n\n return data.join(' ');\n}\n\nMOUNT_CLASS_TO.generatePathData = generatePathData;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {PhotoSize} from '../layer';\nimport {MyDocument} from '../lib/appManagers/appDocsManager';\nimport {MyPhoto} from '../lib/appManagers/appPhotosManager';\nimport {renderImageFromUrlPromise} from './dom/renderImageFromUrl';\nimport getPreviewURLFromThumb from './getPreviewURLFromThumb';\nimport blur from './blur';\n\nexport default function getImageFromStrippedThumb(\n photo: MyPhoto | MyDocument,\n thumb: PhotoSize.photoCachedSize | PhotoSize.photoStrippedSize,\n useBlur: boolean\n) {\n const url = getPreviewURLFromThumb(photo, thumb, false);\n\n let element: HTMLImageElement | HTMLCanvasElement, loadPromise: Promise<void>;\n if(!useBlur) {\n element = new Image();\n loadPromise = renderImageFromUrlPromise(element, url);\n } else {\n const result = blur(url);\n element = result.canvas;\n loadPromise = result.promise;\n }\n\n element.classList.add('thumbnail');\n\n return {image: element, loadPromise};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../lib/appManagers/appDocsManager';\nimport type {MyPhoto} from '../lib/appManagers/appPhotosManager';\nimport {PhotoSize} from '../layer';\n// import appDownloadManager from \"../lib/appManagers/appDownloadManager\";\nimport getPreviewURLFromBytes from './bytes/getPreviewURLFromBytes';\n\nexport default function getPreviewURLFromThumb(photo: MyPhoto | MyDocument, thumb: PhotoSize.photoCachedSize | PhotoSize.photoStrippedSize, isSticker = false) {\n // const cacheContext = appDownloadManager.getCacheContext(photo, thumb.type);\n // return cacheContext.url || (cacheContext.url = getPreviewURLFromBytes(thumb.bytes, isSticker));\n return getPreviewURLFromBytes(thumb.bytes, isSticker);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../lib/appManagers/appDocsManager';\nimport type {MyPhoto} from '../lib/appManagers/appPhotosManager';\nimport {THUMB_TYPE_FULL} from '../lib/mtproto/mtproto_config';\nimport type {ThumbCache} from '../lib/storages/thumbs';\nimport getImageFromStrippedThumb from './getImageFromStrippedThumb';\n\nexport default function getStrippedThumbIfNeeded(photo: MyPhoto | MyDocument, cacheContext: ThumbCache, useBlur: boolean, ignoreCache = false) {\n const isVideo = (['video', 'gif'] as MyDocument['type'][]).includes((photo as MyDocument).type);\n if(!cacheContext.downloaded || isVideo || ignoreCache) {\n if(\n photo._ === 'document' &&\n cacheContext.downloaded &&\n !ignoreCache &&\n (!isVideo || cacheContext.type !== THUMB_TYPE_FULL)\n ) {\n return null;\n }\n\n const sizes = (photo as MyPhoto).sizes || (photo as MyDocument).thumbs;\n const thumb = sizes?.length ? sizes.find((size) => size._ === 'photoStrippedSize') : null;\n if(thumb && ('bytes' in thumb)) {\n return getImageFromStrippedThumb(photo, thumb as any, useBlur);\n }\n }\n\n return null;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport forEachReverse from './array/forEachReverse';\nimport safeAssign from './object/safeAssign';\n\nexport type ListLoaderOptions<T extends {}, P extends {}> = {\n loadMore: ListLoader<T, P>['loadMore'],\n loadCount?: ListLoader<T, P>['loadCount'],\n loadWhenLeft?: ListLoader<T, P>['loadWhenLeft'],\n processItem?: ListLoader<T, P>['processItem'],\n onJump?: ListLoader<T, P>['onJump'],\n onLoadedMore?: ListLoader<T, P>['onLoadedMore']\n};\n\nexport type ListLoaderResult<T extends {}> = {count: number, items: any[]};\nexport default class ListLoader<T extends {}, P extends {}> {\n public current: T;\n public previous: T[] = [];\n public next: T[] = [];\n public count: number;\n public reverse = false; // reverse means next = higher msgid\n\n protected loadMore: (anchor: T, older: boolean, loadCount: number) => Promise<ListLoaderResult<T>>;\n protected processItem: (item: P) => T | Promise<T>;\n protected loadCount = 50;\n protected loadWhenLeft = 20;\n\n public onJump: (item: T, older: boolean) => void;\n public onLoadedMore: () => void;\n\n protected loadedAllUp = false;\n protected loadedAllDown = false;\n protected loadPromiseUp: Promise<void>;\n protected loadPromiseDown: Promise<void>;\n\n constructor(options: ListLoaderOptions<T, P>) {\n safeAssign(this, options);\n }\n\n public setTargets(previous: T[], next: T[], reverse: boolean) {\n this.previous = previous;\n this.next = next;\n this.reverse = reverse;\n }\n\n public get index() {\n return this.count !== undefined ? this.previous.length : -1;\n }\n\n /* public filter(callback: (item: T, idx: number, arr: T[]) => boolean) {\n const filter = (item: T, idx: number, arr: T[]) => {\n if(!callback(item, idx, arr)) {\n arr.splice(idx, 1);\n }\n };\n\n forEachReverse(this.previous, filter);\n forEachReverse(this.next, filter);\n } */\n\n public reset(loadedAll = false) {\n this.current = undefined;\n this.previous = [];\n this.next = [];\n this.setLoaded(true, loadedAll);\n this.setLoaded(false, loadedAll);\n }\n\n public go(length: number, dispatchJump = true) {\n let items: T[], item: T;\n if(length > 0) {\n items = this.next.splice(0, length);\n item = items.pop();\n if(!item) {\n return;\n }\n\n if(this.current !== undefined) items.unshift(this.current);\n this.previous.push(...items);\n } else {\n items = this.previous.splice(Math.max(0, this.previous.length + length), -length);\n item = items.shift();\n if(!item) {\n return;\n }\n\n if(this.current !== undefined) items.push(this.current);\n this.next.unshift(...items);\n }\n\n if(this.next.length < this.loadWhenLeft) {\n this.load(!this.reverse);\n }\n\n if(this.previous.length < this.loadWhenLeft) {\n this.load(this.reverse);\n }\n\n this.current = item;\n dispatchJump && this.onJump && this.onJump(item, length > 0);\n return this.current;\n }\n\n protected unsetCurrent(toPrevious: boolean) {\n if(toPrevious) this.previous.push(this.current);\n else this.next.unshift(this.current);\n\n this.current = undefined;\n }\n\n public goUnsafe(length: number, dispatchJump?: boolean) {\n const leftLength = length > 0 ? Math.max(0, length - this.next.length) : Math.min(0, length + this.previous.length);\n const item = this.go(length, leftLength ? false : dispatchJump);\n\n /* if(length > 0 ? this.loadedAllUp : this.loadedAllDown) {\n this.unsetCurrent(length > 0);\n } */\n\n return {\n item: !leftLength ? item : undefined,\n leftLength\n };\n }\n\n protected setLoaded(down: boolean, value: boolean) {\n const isChanged = (down ? this.loadedAllDown : this.loadedAllUp) !== value;\n if(!isChanged) {\n return false;\n }\n\n if(down) this.loadedAllDown = value;\n else this.loadedAllUp = value;\n\n if(!value) {\n if(down) this.loadPromiseDown = null;\n else this.loadPromiseUp = null;\n }\n\n return true;\n }\n\n // нет смысла делать проверку для reverse и loadMediaPromise\n public load(older: boolean) {\n if(older ? this.loadedAllDown : this.loadedAllUp) return Promise.resolve();\n\n let promise = older ? this.loadPromiseDown : this.loadPromiseUp;\n if(promise) return promise;\n\n let anchor: T;\n if(older) {\n anchor = this.reverse ? this.previous[0] : this.next[this.next.length - 1];\n } else {\n anchor = this.reverse ? this.next[this.next.length - 1] : this.previous[0];\n }\n\n anchor ??= this.current;\n promise = this.loadMore(anchor, older, this.loadCount).then(async(result) => {\n if((older ? this.loadPromiseDown : this.loadPromiseUp) !== promise) {\n return;\n }\n\n if(result.items.length < this.loadCount) {\n this.setLoaded(older, true);\n }\n\n if(this.count === undefined) {\n this.count = result.count || result.items.length;\n }\n\n const processedArr: (Promise<any> | any)[] = [];\n const method = older ? result.items.forEach.bind(result.items) : forEachReverse.bind(null, result.items);\n method((item: any) => {\n const processed = this.processItem ? this.processItem(item) : item;\n\n if(!processed) return;\n processedArr.push(processed);\n });\n\n const results = await Promise.all(processedArr);\n if(older) {\n if(this.reverse) this.previous.unshift(...results);\n else this.next.push(...results);\n } else {\n if(this.reverse) this.next.push(...results);\n else this.previous.unshift(...results);\n }\n\n this.onLoadedMore && this.onLoadedMore();\n }, () => {}).then(() => {\n if(older) this.loadPromiseDown = null;\n else this.loadPromiseUp = null;\n });\n\n if(older) this.loadPromiseDown = promise;\n else this.loadPromiseUp = promise;\n\n return promise;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type EventListenerBase from './eventListenerBase';\n\nexport type Listener = {\n element: ListenerElement,\n event: ListenerEvent,\n callback: ListenerCallback,\n options?: ListenerOptions,\n\n onceFired?: true, // will be set only when options.once is set\n onceCallback?: () => void,\n};\n\nexport type ListenerElement = Window | Document | HTMLElement | Element | EventListenerBase<any>;\nexport type ListenerEvent = string;\nexport type ListenerCallback = Function;\nexport type ListenerOptions = AddEventListenerOptions;\n\n/* const originalAddEventListener = HTMLElement.prototype.addEventListener;\nHTMLElement.prototype.addEventListener = function(this, name: string, callback: EventListenerOrEventListenerObject, options: AddEventListenerOptions) {\n console.log('nu zdarova', name);\n originalAddEventListener.call(this, name, callback, options);\n\n if(options?.ls) {\n return options.ls.addFromElement(this, name, callback as any, options);\n }\n}; */\n\nexport default class ListenerSetter {\n private listeners: Set<Listener> = new Set();\n\n public add<T extends ListenerElement>(element: T): T['addEventListener'] {\n return ((event: string, callback: Function, options: ListenerOptions) => {\n const listener: Listener = {element, event, callback, options};\n this.addManual(listener);\n return listener;\n }) as any;\n }\n\n /* public addFromElement<T extends ListenerElement>(element: T, event: ListenerEvent, callback: ListenerCallback, options: ListenerOptions) {\n const listener: Listener = {element, event, callback, options};\n this.addManual(listener);\n return listener;\n } */\n\n public addManual(listener: Listener) {\n // @ts-ignore\n listener.element.addEventListener(listener.event, listener.callback, listener.options);\n\n if(listener.options?.once) { // remove listener when its called\n listener.onceCallback = () => {\n this.remove(listener);\n listener.onceFired = true;\n };\n\n // @ts-ignore\n listener.element.addEventListener(listener.event, listener.onceCallback, listener.options);\n }\n\n this.listeners.add(listener);\n }\n\n public remove(listener: Listener) {\n if(!listener.onceFired) {\n // @ts-ignore\n listener.element.removeEventListener(listener.event, listener.callback, listener.options);\n\n if(listener.onceCallback) {\n // @ts-ignore\n listener.element.removeEventListener(listener.event, listener.onceCallback, listener.options);\n }\n }\n\n this.listeners.delete(listener);\n }\n\n public removeManual<T extends ListenerElement>(\n element: T,\n event: ListenerEvent,\n callback: ListenerCallback,\n options?: ListenerOptions\n ) {\n let listener: Listener;\n for(const _listener of this.listeners) {\n if(_listener.element === element &&\n _listener.event === event &&\n _listener.callback === callback &&\n _listener.options === options) {\n listener = _listener;\n break;\n }\n }\n\n if(listener) {\n this.remove(listener);\n }\n }\n\n public removeAll() {\n this.listeners.forEach((listener) => {\n this.remove(listener);\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport rootScope from '../lib/rootScope';\n\nexport type LiteModeKey = 'all' | 'gif' | 'video' |\n 'emoji' | 'emoji_panel' | 'emoji_messages' |\n 'effects' | 'effects_reactions' | 'effects_premiumstickers' | 'effects_emoji' |\n 'stickers' | 'stickers_panel' | 'stickers_chat' |\n 'chat' | 'chat_background' | 'chat_spoilers' | 'animations';\n\nexport class LiteMode {\n public isEnabled() {\n return rootScope.settings.liteMode.all;\n }\n\n public isAvailable(key: LiteModeKey) {\n return !rootScope.settings.liteMode.all && !rootScope.settings.liteMode[key];\n }\n}\n\nconst liteMode = new LiteMode();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.liteMode = liteMode);\nexport default liteMode;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport calcImageInBox from './calcImageInBox';\n\nexport class MediaSize {\n constructor(public width = 0, public height = width) {\n\n }\n\n public aspect(boxSize: MediaSize, fitted: boolean) {\n return calcImageInBox(this.width, this.height, boxSize.width, boxSize.height, fitted);\n }\n\n public aspectFitted(boxSize: MediaSize) {\n return this.aspect(boxSize, true);\n }\n\n public aspectCovered(boxSize: MediaSize) {\n return this.aspect(boxSize, false);\n }\n}\n\nexport function makeMediaSize(width?: number, height?: number): MediaSize {\n return new MediaSize(width, height);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport EventListenerBase from './eventListenerBase';\nimport {makeMediaSize, MediaSize} from './mediaSize';\n\ntype MediaTypeSizes = {\n regular: MediaSize,\n webpage: MediaSize,\n album: MediaSize,\n esgSticker: MediaSize,\n animatedSticker: MediaSize,\n staticSticker: MediaSize,\n emojiSticker: MediaSize,\n poll: MediaSize,\n round: MediaSize,\n documentName: MediaSize,\n invoice: MediaSize,\n extendedInvoice: MediaSize,\n customEmoji: MediaSize,\n esgCustomEmoji: MediaSize,\n emojiStatus: MediaSize,\n popupSticker: MediaSize\n};\n\nexport type MediaSizeType = keyof MediaTypeSizes;\n\nexport enum ScreenSize {\n mobile,\n medium,\n large\n}\n\nconst MOBILE_SIZE = 600;\nconst MEDIUM_SIZE = 1275;\nconst LARGE_SIZE = 1680;\n\nconst CUSTOM_EMOJI_SIZE = makeMediaSize(20, 20);\nconst ESG_CUSTOM_EMOJI_SIZE = makeMediaSize(36, 36);\nconst EMOJI_STATUS_SIZE = makeMediaSize(18, 18);\n\nclass MediaSizes extends EventListenerBase<{\n changeScreen: (from: ScreenSize, to: ScreenSize) => void,\n resize: () => void\n}> {\n private screenSizes: {key: ScreenSize, value: number}[] = [\n {key: ScreenSize.mobile, value: MOBILE_SIZE},\n {key: ScreenSize.medium, value: MEDIUM_SIZE},\n {key: ScreenSize.large, value: LARGE_SIZE}\n ];\n\n private sizes: {[k in 'desktop' | 'handhelds']: MediaTypeSizes} = {\n handhelds: {\n regular: makeMediaSize(270, 270),\n webpage: makeMediaSize(270, 200),\n album: makeMediaSize(270, 0),\n esgSticker: makeMediaSize(68, 68),\n animatedSticker: makeMediaSize(180, 180),\n staticSticker: makeMediaSize(180, 180),\n emojiSticker: makeMediaSize(112, 112),\n poll: makeMediaSize(240, 0),\n round: makeMediaSize(200, 200),\n documentName: makeMediaSize(200, 0),\n invoice: makeMediaSize(270, 270),\n extendedInvoice: makeMediaSize(270, 270),\n customEmoji: CUSTOM_EMOJI_SIZE,\n esgCustomEmoji: ESG_CUSTOM_EMOJI_SIZE,\n emojiStatus: EMOJI_STATUS_SIZE,\n popupSticker: makeMediaSize(68, 68)\n },\n desktop: {\n regular: makeMediaSize(420, 340),\n webpage: makeMediaSize(420, 340),\n album: makeMediaSize(420, 0),\n esgSticker: makeMediaSize(72, 72),\n animatedSticker: makeMediaSize(200, 200),\n staticSticker: makeMediaSize(200, 200),\n emojiSticker: makeMediaSize(112, 112),\n poll: makeMediaSize(330, 0),\n round: makeMediaSize(280, 280),\n documentName: makeMediaSize(240, 0),\n invoice: makeMediaSize(320, 320),\n extendedInvoice: makeMediaSize(420, 340),\n customEmoji: CUSTOM_EMOJI_SIZE,\n esgCustomEmoji: ESG_CUSTOM_EMOJI_SIZE,\n emojiStatus: EMOJI_STATUS_SIZE,\n popupSticker: makeMediaSize(80, 80)\n }\n };\n\n public isMobile = false;\n public active: MediaTypeSizes;\n public activeScreen: ScreenSize;\n private rAF: number;\n\n constructor() {\n super();\n\n window.addEventListener('resize', () => {\n if(this.rAF) window.cancelAnimationFrame(this.rAF);\n this.rAF = window.requestAnimationFrame(() => {\n this.handleResize();\n this.rAF = 0;\n });\n });\n this.handleResize();\n }\n\n private handleResize = () => {\n const innerWidth = window.innerWidth;\n // this.isMobile = innerWidth <= 720;\n\n let activeScreen = this.screenSizes[0].key;\n for(let i = this.screenSizes.length - 1; i >= 0; --i) {\n if(this.screenSizes[i].value < innerWidth) {\n activeScreen = (this.screenSizes[i + 1] || this.screenSizes[i]).key;\n break;\n }\n }\n\n const wasScreen = this.activeScreen;\n this.activeScreen = activeScreen;\n this.isMobile = this.activeScreen === ScreenSize.mobile;\n this.active = this.isMobile ? this.sizes.handhelds : this.sizes.desktop;\n\n // console.time('esg');\n // const computedStyle = window.getComputedStyle(document.documentElement);\n // this.active.esgSticker.width = parseFloat(computedStyle.getPropertyValue('--esg-sticker-size'));\n // console.timeEnd('esg');\n\n if(wasScreen !== activeScreen) {\n // console.log('changeScreen', this.activeScreen, activeScreen);\n\n if(wasScreen !== undefined) {\n this.dispatchEvent('changeScreen', wasScreen, activeScreen);\n }\n }\n\n if(wasScreen !== undefined) {\n this.dispatchEvent('resize');\n }\n\n /* if(this.isMobile) {\n for(let i in this.active) {\n // @ts-ignore\n let size = this.active[i];\n size.width = innerWidth\n }\n } */\n };\n}\n\nconst mediaSizes = new MediaSizes();\nMOUNT_CLASS_TO.mediaSizes = mediaSizes;\nexport default mediaSizes;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport makeError from './makeError';\n\nconst error = makeError('MIDDLEWARE');\nexport default function middlewarePromise(middleware: () => boolean, throwWhat: any = error) {\n return <T>(promise: T): T => {\n if(!(promise instanceof Promise)) {\n if(promise instanceof Error) {\n throw promise;\n } else {\n return promise;\n }\n }\n\n return (promise as any as Promise<any>).then((result) => {\n if(!middleware()) {\n throw throwWhat;\n }\n\n return result;\n }) as any;\n };\n}\n","export default function formatNumber(bytes: number, decimals = 2) {\n if(bytes === 0) return '0';\n\n const k = 1000;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = ['', 'K', 'M', 'B', 'T'];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i];\n}\n","export default function numberThousandSplitter(x: number, joiner = ' ') {\n const parts = x.toString().split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, joiner);\n return parts.join('.');\n}\n","import {IS_APPLE_MOBILE} from '../environment/userAgent';\n\nexport default function onMediaLoad(media: HTMLMediaElement, readyState = media.HAVE_METADATA, useCanplayOnIos?: boolean) {\n return new Promise<void>((resolve, reject) => {\n if(media.readyState >= readyState) {\n resolve();\n return;\n }\n\n const loadEventName = IS_APPLE_MOBILE && !useCanplayOnIos ? 'loadeddata' : 'canplay';\n const errorEventName = 'error';\n const onLoad = () => {\n media.removeEventListener(errorEventName, onError);\n resolve();\n };\n const onError = (e: ErrorEvent) => {\n media.removeEventListener(loadEventName, onLoad);\n reject(media.error);\n };\n media.addEventListener(loadEventName, onLoad, {once: true});\n media.addEventListener(errorEventName, onError, {once: true});\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport appNavigationController, {NavigationItem} from '../components/appNavigationController';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport {IS_MOBILE_SAFARI} from '../environment/userAgent';\nimport cancelEvent from './dom/cancelEvent';\nimport {CLICK_EVENT_NAME, hasMouseMovedSinceDown} from './dom/clickEvent';\nimport findUpAsChild from './dom/findUpAsChild';\nimport EventListenerBase from './eventListenerBase';\n\nexport default class OverlayClickHandler extends EventListenerBase<{\n toggle: (open: boolean) => void\n}> {\n protected element: HTMLElement;\n protected overlay: HTMLElement;\n protected listenerOptions: AddEventListenerOptions;\n\n constructor(\n protected navigationType: NavigationItem['type'],\n protected withOverlay?: boolean\n ) {\n super(false);\n this.listenerOptions = withOverlay ? {} : {capture: true};\n }\n\n protected onClick = (e: MouseEvent | TouchEvent) => {\n if(hasMouseMovedSinceDown(e)) {\n return;\n }\n\n if(this.element && findUpAsChild(e.target as HTMLElement, this.element)) {\n return;\n }\n\n if(this.listenerOptions?.capture) {\n cancelEvent(e);\n }\n\n this.close();\n };\n\n public close() {\n if(this.element) {\n this.overlay?.remove();\n this.element = undefined;\n this.dispatchEvent('toggle', false);\n }\n\n if(!IS_TOUCH_SUPPORTED) {\n // window.removeEventListener('keydown', onKeyDown, {capture: true});\n window.removeEventListener('contextmenu', this.onClick, this.listenerOptions);\n }\n\n document.removeEventListener(CLICK_EVENT_NAME, this.onClick, this.listenerOptions);\n\n if(!IS_MOBILE_SAFARI) {\n appNavigationController.removeByType(this.navigationType);\n }\n }\n\n public open(element: HTMLElement) {\n this.close();\n\n if(!IS_MOBILE_SAFARI) {\n appNavigationController.pushItem({\n type: this.navigationType,\n onPop: (canAnimate) => {\n this.close();\n }\n });\n }\n\n this.element = element;\n\n if(!this.overlay && this.withOverlay) {\n this.overlay = document.createElement('div');\n this.overlay.classList.add('btn-menu-overlay');\n\n // ! because this event must be canceled, and can't cancel on menu click (below)\n this.overlay.addEventListener(CLICK_EVENT_NAME, (e) => {\n cancelEvent(e);\n this.onClick(e);\n });\n }\n\n this.overlay && this.element.parentElement.insertBefore(this.overlay, this.element);\n\n // document.body.classList.add('disable-hover');\n\n if(!IS_TOUCH_SUPPORTED) {\n // window.addEventListener('keydown', onKeyDown, {capture: true});\n window.addEventListener('contextmenu', this.onClick, {...this.listenerOptions, once: true});\n }\n\n /* // ! because this event must be canceled, and can't cancel on menu click (below)\n overlay.addEventListener(CLICK_EVENT_NAME, (e) => {\n cancelEvent(e);\n onClick(e);\n }); */\n\n // ! safari iOS doesn't handle window click event on overlay, idk why\n document.addEventListener(CLICK_EVENT_NAME, this.onClick, this.listenerOptions);\n\n this.dispatchEvent('toggle', true);\n }\n}\n","import Currencies from '../config/currencies';\n\n// https://stackoverflow.com/a/34141813\nfunction number_format(number: any, decimals: any, dec_point: any, thousands_sep: any): string {\n // Strip all characters but numerical ones.\n number = (number + '').replace(/[^0-9+\\-Ee.]/g, '');\n var n = !isFinite(+number) ? 0 : +number,\n prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),\n sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,\n dec = (typeof dec_point === 'undefined') ? '.' : dec_point,\n s: any = '',\n toFixedFix = function(n: number, prec: number) {\n var k = Math.pow(10, prec);\n return '' + Math.round(n * k) / k;\n };\n // Fix for IE parseFloat(0.55).toFixed(0) = 0;\n s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');\n if(s[0].length > 3) {\n s[0] = s[0].replace(/\\B(?=(?:\\d{3})+(?!\\d))/g, sep);\n }\n if((s[1] || '').length < prec) {\n s[1] = s[1] || '';\n s[1] += new Array(prec - s[1].length + 1).join('0');\n }\n return s.join(dec);\n}\n\nexport default function paymentsWrapCurrencyAmount(\n amount: number | string,\n currency: string,\n skipSymbol?: boolean,\n useNative?: boolean\n) {\n amount = +amount;\n\n const isNegative = amount < 0;\n\n const currencyData = Currencies[currency];\n if(!currencyData) {\n throw new Error('CURRENCY_WRAP_INVALID');\n }\n\n const amountExp = amount / Math.pow(10, currencyData.exp);\n\n let decimals = currencyData.exp;\n if(currency == 'IRR' && Math.floor(amountExp) == amountExp) {\n decimals = 0; // у иранцев копейки почти всегда = 0 и не показываются в UI\n }\n\n let formatted = number_format(amountExp, decimals, currencyData.decimal_sep, currencyData.thousands_sep);\n if(skipSymbol) {\n return formatted;\n }\n\n let symbol = useNative ? currencyData.native || currencyData.symbol : currencyData.symbol;\n if(isNegative && !currencyData.space_between && currencyData.symbol_left) {\n symbol = '-' + symbol;\n formatted = formatted.replace('-', '');\n }\n\n let out: string;\n const splitter = currencyData.space_between ? ' ' : '';\n if(currencyData.symbol_left) {\n out = symbol + splitter + formatted;\n } else {\n out = formatted + splitter + symbol;\n }\n return out;\n}\n\n(window as any).p = paymentsWrapCurrencyAmount;\n\n// function paymentsGetCurrencyExp($currency: string) {\n// if($currency == 'CLF') {\n// return 4;\n// }\n// if(['BHD','IQD','JOD','KWD','LYD','OMR','TND'].includes($currency)) {\n// return 3;\n// }\n// if(['BIF','BYR','CLP','CVE','DJF','GNF','ISK','JPY','KMF','KRW','MGA', 'PYG','RWF','UGX','UYI','VND','VUV','XAF','XOF','XPF'].includes($currency)) {\n// return 0;\n// }\n// if($currency == 'MRO') {\n// return 1;\n// }\n// return 2;\n// }\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport mediaSizes from './mediaSizes';\n\nexport type MenuPositionPadding = {\n top?: number,\n right?: number,\n bottom?: number,\n left?: number\n};\n\nconst PADDING_TOP = 8;\nconst PADDING_BOTTOM = PADDING_TOP;\nconst PADDING_LEFT = 8;\nconst PADDING_RIGHT = PADDING_LEFT;\nexport default function positionMenu(e: MouseEvent | Touch | TouchEvent, elem: HTMLElement, side?: 'left' | 'right' | 'center', additionalPadding?: MenuPositionPadding) {\n if((e as TouchEvent).touches) {\n e = (e as TouchEvent).touches[0];\n }\n\n const {pageX, pageY} = e as Touch;\n // let {clientX, clientY} = e;\n\n // * side mean the OPEN side\n\n const getScrollWidthFromElement = (Array.from(elem.children) as HTMLElement[]).find((element) => element.classList.contains('btn-menu-item') && !element.classList.contains('hide')) || elem;\n\n let {scrollWidth: menuWidth} = getScrollWidthFromElement;\n const {scrollHeight: menuHeight} = elem;\n // let {innerWidth: windowWidth, innerHeight: windowHeight} = window;\n const rect = document.body.getBoundingClientRect();\n const windowWidth = rect.width;\n const windowHeight = rect.height;\n\n menuWidth += getScrollWidthFromElement.offsetLeft * 2;\n\n let paddingTop = PADDING_TOP, paddingRight = PADDING_RIGHT, paddingBottom = PADDING_BOTTOM, paddingLeft = PADDING_LEFT;\n if(additionalPadding) {\n if(additionalPadding.top) paddingTop += additionalPadding.top;\n if(additionalPadding.right) paddingRight += additionalPadding.right;\n if(additionalPadding.bottom) paddingBottom += additionalPadding.bottom;\n if(additionalPadding.left) paddingLeft += additionalPadding.left;\n }\n\n side = mediaSizes.isMobile ? 'right' : 'left';\n let verticalSide: 'top' /* | 'bottom' */ | 'center' = 'top';\n\n const maxTop = windowHeight - menuHeight - paddingBottom;\n const maxLeft = windowWidth - menuWidth - paddingRight;\n const minTop = paddingTop;\n const minLeft = paddingLeft;\n\n const getSides = () => {\n return {\n x: {\n left: pageX,\n right: Math.min(maxLeft, pageX - menuWidth)\n },\n intermediateX: side === 'right' ? minLeft : maxLeft,\n // intermediateX: clientX < windowWidth / 2 ? PADDING_LEFT : windowWidth - menuWidth - PADDING_LEFT,\n y: {\n top: pageY,\n bottom: pageY - menuHeight\n },\n // intermediateY: verticalSide === 'top' ? paddingTop : windowHeight - menuHeight - paddingTop,\n // intermediateY: pageY < (windowHeight / 2) ? paddingTop : windowHeight - menuHeight - paddingBottom,\n intermediateY: maxTop\n };\n };\n\n const sides = getSides();\n\n const possibleSides = {\n x: {\n left: (sides.x.left + menuWidth + paddingRight) <= windowWidth,\n right: sides.x.right >= paddingLeft\n },\n y: {\n top: (sides.y.top + menuHeight + paddingBottom) <= windowHeight,\n bottom: (sides.y.bottom - paddingBottom) >= paddingBottom\n }\n };\n\n /* if(side === undefined) {\n if((clientX + menuWidth + PADDING_LEFT) > windowWidth) {\n side = 'right';\n }\n } */\n\n {\n /* const x = sides.x;\n\n const s = Object.keys(x) as (keyof typeof possibleSides.x)[];\n if(side) {\n s.findAndSplice((s) => s === side);\n s.unshift(side);\n }\n\n const possibleSide = s.find((s) => possibleSides.x[s]); */\n // let left: number;\n /* if(possibleSide) {\n left = x[possibleSide];\n side = possibleSide;\n } else {\n left = sides.intermediateX;\n side = undefined;\n } */\n const left = possibleSides.x[side] ? sides.x[side] : (side = 'center', sides.intermediateX);\n\n elem.style.left = left + 'px';\n }\n\n /* if((clientY + menuHeight + PADDING_TOP) > windowHeight) {\n elem.style.top = clamp(clientY - menuHeight, PADDING_TOP, windowHeight - menuHeight - PADDING_TOP) + 'px';\n // elem.style.top = (innerHeight - scrollHeight - PADDING_TOP) + 'px';\n verticalSide = 'bottom';\n } else {\n elem.style.top = Math.max(PADDING_TOP, clientY) + 'px';\n verticalSide = 'top';\n } */\n\n {\n const top = possibleSides.y[verticalSide] ? sides.y[verticalSide] : (verticalSide = 'center', sides.intermediateY);\n\n elem.style.top = top + 'px';\n }\n\n elem.className = elem.className.replace(/(top|center|bottom)-(left|center|right)/g, '');\n elem.classList.add(\n // (verticalSide === 'center' ? verticalSide : (verticalSide === 'bottom' ? 'top' : 'bottom')) +\n (verticalSide === 'center' ? verticalSide : 'bottom') +\n '-' +\n (side === 'center' ? side : (side === 'left' ? 'right' : 'left')));\n\n return {\n width: menuWidth,\n height: menuHeight\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport appDownloadManager from '../lib/appManagers/appDownloadManager';\nimport lottieLoader from '../lib/rlottie/lottieLoader';\nimport rootScope from '../lib/rootScope';\nimport {getEmojiToneIndex} from '../vendor/emoji';\nimport mediaSizes from './mediaSizes';\nimport {saveLottiePreview} from './saveLottiePreview';\n\nexport default function preloadAnimatedEmojiSticker(emoji: string, width?: number, height?: number) {\n return rootScope.managers.appStickersManager.preloadAnimatedEmojiSticker(emoji).then(({doc}) => {\n if(!doc) {\n return;\n }\n\n return appDownloadManager.downloadMedia({media: doc})\n .then(async(blob) => {\n const mediaSize = mediaSizes.active.emojiSticker;\n const toneIndex = getEmojiToneIndex(emoji);\n const animation = await lottieLoader.loadAnimationWorker({\n container: undefined,\n animationData: blob,\n width: width ?? mediaSize.width,\n height: height ?? mediaSize.height,\n name: 'doc' + doc.id,\n autoplay: false,\n loop: false,\n toneIndex,\n group: 'none'\n });\n\n animation.addEventListener('firstFrame', () => {\n saveLottiePreview(doc, animation.canvas[0], toneIndex);\n animation.remove();\n }, {once: true});\n });\n });\n}\n","import {RestrictionReason} from '../layer';\n\nconst platforms = new Set([\n 'all',\n 'web',\n 'webk'\n]);\n\nconst ignore = new Set();\n\nexport function getRestrictionReason(reasons: RestrictionReason[]) {\n // return reasons[0];\n return reasons.find((reason) => platforms.has(reason.platform) && !ignore.has(reason.reason));\n}\n\nexport function isRestricted(reasons: RestrictionReason[]) {\n return !!getRestrictionReason(reasons);\n}\n\nexport function ignoreRestrictionReasons(reasons: string[]) {\n ignore.clear();\n reasons.forEach((reason) => {\n ignore.add(reason);\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../lib/appManagers/appDocsManager';\nimport rootScope from '../lib/rootScope';\n\nconst savingLottiePreview: {[docId: DocId]: {width: number, height: number}} = {};\n\nexport function isSavingLottiePreview(doc: MyDocument, toneIndex: number, width: number, height: number) {\n const key = doc.id + '-' + toneIndex;\n const saving = savingLottiePreview[key];\n return saving && saving.width >= width && saving.height >= height;\n}\n\nexport async function saveLottiePreview(doc: MyDocument, canvas: HTMLCanvasElement, toneIndex: number) {\n const key = doc.id + '-' + toneIndex;\n const {width, height} = canvas;\n if(isSavingLottiePreview(doc, toneIndex, width, height)) {\n return;\n }\n\n const saving = savingLottiePreview[key] = {\n width,\n height\n };\n\n const thumb = await rootScope.managers.appDocsManager.getLottieCachedThumb(doc.id, toneIndex);\n if(savingLottiePreview[key] !== saving) {\n return;\n }\n\n if(thumb && thumb.w >= width && thumb.h >= height) {\n return;\n }\n\n const promise = new Promise<Blob>((resolve) => {\n canvas.toBlob((blob) => resolve(blob));\n });\n\n const blob = await promise;\n if(savingLottiePreview[key] !== saving) {\n return;\n }\n\n // console.log('got lottie preview', doc, blob, URL.createObjectURL(blob));\n\n rootScope.managers.appDocsManager.saveLottiePreview(doc.id, blob, width, height, toneIndex);\n\n // delete savingLottiePreview[key];\n\n /* const reader = new FileReader();\n reader.onloadend = (e) => {\n const uint8 = new Uint8Array(e.target.result as ArrayBuffer);\n const thumb: PhotoSize.photoStrippedSize = {\n _: 'photoStrippedSize',\n bytes: uint8,\n type: 'i'\n };\n\n doc.stickerSavedThumbWidth = canvas.width;\n doc.stickerSavedThumbHeight = canvas.width;\n\n defineNotNumerableProperties(thumb, ['url']);\n thumb.url = URL.createObjectURL(blob);\n doc.thumbs.findAndSplice((t) => t._ === thumb._);\n doc.thumbs.unshift(thumb);\n\n if(!webpWorkerController.isWebpSupported()) {\n doc.pFlags.stickerThumbConverted = true;\n }\n\n delete this.savingLottiePreview[doc.id];\n };\n reader.readAsArrayBuffer(blob); */\n}\n","// * Jolly Cobra's schedulers\n\nimport {AnyToVoidFunction} from '../../types';\nimport {fastRaf} from '../schedulers';\nimport throttleWith from './throttleWith';\n\nexport default function throttleWithRaf<F extends AnyToVoidFunction>(fn: F) {\n return throttleWith(fastRaf, fn);\n}\n","// * Jolly Cobra's schedulers\n\nimport {AnyToVoidFunction} from '../../types';\n\nexport default function throttleWith<F extends AnyToVoidFunction>(schedulerFn: AnyToVoidFunction, fn: F) {\n let waiting = false;\n let args: Parameters<F>;\n\n return (..._args: Parameters<F>) => {\n args = _args;\n\n if(!waiting) {\n waiting = true;\n\n schedulerFn(() => {\n waiting = false;\n // @ts-ignore\n fn(...args);\n });\n }\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport Scrollable from '../components/scrollable';\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport {IS_SAFARI} from '../environment/userAgent';\nimport getVisibleRect from './dom/getVisibleRect';\nimport reflowScrollableElement from './dom/reflowScrollableElement';\n\nexport default class ScrollSaver {\n private scrollHeight: number;\n private scrollHeightMinusTop: number;\n private scrollTop: number;\n private clientHeight: number;\n private elements: {element: HTMLElement, rect: DOMRect}[];\n\n /**\n *\n * @param scrollable to reset scroll position and direction\n * @param reverse true means top\n */\n constructor(\n private scrollable: Scrollable,\n private query: string,\n private reverse: boolean\n ) {\n\n }\n\n private get container() {\n return this.scrollable.container;\n }\n\n public getSaved() {\n return {\n scrollHeight: this.scrollHeight,\n scrollTop: this.scrollTop,\n clientHeight: this.clientHeight\n };\n }\n\n public findElements() {\n if(!this.query) return [];\n\n const {container} = this;\n const containerRect = container.getBoundingClientRect();\n const bubbles = Array.from(container.querySelectorAll(this.query)) as HTMLElement[];\n const elements: ScrollSaver['elements'] = [];\n for(const bubble of bubbles) {\n const elementRect = bubble.getBoundingClientRect();\n const visibleRect = getVisibleRect(bubble, container, undefined, elementRect, containerRect);\n if(visibleRect) {\n elements.push({element: bubble, rect: elementRect});\n // break; // find first\n } else if(elements.length) { // find last\n break;\n }\n }\n\n if(!elements.length) {\n const bubble = bubbles[0];\n if(bubble) {\n elements.push({element: bubble, rect: bubble.getBoundingClientRect()});\n }\n }\n\n return elements;\n }\n\n public replaceSaved(from: HTMLElement, to: HTMLElement) {\n if(!this.elements) {\n return;\n }\n\n const idx = this.elements.findIndex(({element}) => from === element);\n if(idx !== -1) {\n this.elements[idx].element = to;\n }\n }\n\n public findAndSetElements() {\n this.elements = this.findElements();\n }\n\n public save() {\n this.findAndSetElements();\n // console.warn('scroll save', this.elements);\n this._save();\n }\n\n public _save() {\n const {scrollTop, scrollHeight, clientHeight} = this.container;\n\n // previousScrollHeight = scrollHeight;\n // previousScrollHeight = scrollHeight + padding;\n this.scrollHeight = scrollHeight;\n this.scrollTop = scrollTop;\n this.clientHeight = clientHeight;\n this.scrollHeightMinusTop = this.reverse ? scrollHeight - scrollTop : scrollTop;\n\n // this.chatInner.style.paddingTop = padding + 'px';\n /* if(reverse) {\n previousScrollHeightMinusTop = this.scrollable.scrollHeight - scrollTop;\n } else {\n previousScrollHeightMinusTop = scrollTop;\n } */\n }\n\n private onRestore(useReflow?: boolean) {\n if(IS_SAFARI && useReflow/* && !isAppleMobile */) { // * fix blinking and jumping\n reflowScrollableElement(this.container);\n }\n }\n\n private setScrollTop(newScrollTop: number, useReflow?: boolean) {\n // touchSupport for safari iOS\n // isTouchSupported && isApple && (container.container.style.overflow = 'hidden');\n this.scrollable.setScrollTopSilently(this.scrollTop = newScrollTop);\n // container.scrollTop = scrollHeight;\n // isTouchSupported && isApple && (container.container.style.overflow = '');\n\n this.onRestore(useReflow);\n }\n\n public restore(useReflow?: boolean) {\n const {scrollTop, scrollHeight} = this.scrollable;\n this.scrollHeight = scrollHeight;\n\n if(!this.elements.length) { // maybe all messages have been deleted\n this._restore(useReflow);\n return;\n }\n\n let anchor: ScrollSaver['elements'][0];\n // for(let i = this.elements.length - 1; i >= 0; --i) {\n // const _anchor = this.elements[i];\n // if(_anchor.element.parentElement) {\n // anchor = _anchor;\n // break;\n // }\n // }\n anchor = this.elements[this.elements.length - 1];\n\n if(!anchor?.element?.parentElement) { // try to find new anchor\n this.findAndSetElements();\n anchor = this.elements[this.elements.length - 1];\n\n if(!anchor) { // fallback to old method if smth is really strange\n this._restore(useReflow);\n return;\n }\n }\n\n const {element, rect} = anchor;\n const newRect = element.getBoundingClientRect();\n const diff = newRect.bottom - rect.bottom;\n this.setScrollTop(scrollTop + diff, useReflow);\n // if(diff) debugger;\n // console.warn('scroll restore', rect, diff, newRect);\n }\n\n public _restore(useReflow?: boolean) {\n const {scrollHeightMinusTop: previousScrollHeightMinusTop, scrollable} = this;\n // if(previousScrollHeightMinusTop === undefined) {\n // throw new Error('scroll was not saved');\n // }\n\n // const scrollHeight = container.scrollHeight;\n const scrollHeight = this.scrollHeight;\n // if(scrollHeight === this.scrollHeight) {\n // return;\n // }\n\n // this.scrollHeight = scrollHeight;\n\n /* const scrollHeight = container.scrollHeight;\n const addedHeight = scrollHeight - previousScrollHeight;\n\n this.chatInner.style.paddingTop = (10000 - addedHeight) + 'px'; */\n /* const scrollHeight = scrollHeight;\n const addedHeight = scrollHeight - previousScrollHeight;\n\n this.chatInner.style.paddingTop = (padding - addedHeight) + 'px';\n\n //const newScrollTop = reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;\n const newScrollTop = reverse ? scrollHeight - addedHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;\n this.log('performHistoryResult: will set scrollTop',\n previousScrollHeightMinusTop, scrollHeight,\n newScrollTop, container.container.clientHeight); */\n // const newScrollTop = reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;\n const newScrollTop = this.reverse ? scrollHeight - previousScrollHeightMinusTop : previousScrollHeightMinusTop;\n\n /* if(DEBUG) {\n this.log('performHistoryResult: will set up scrollTop:', newScrollTop, this.isHeavyAnimationInProgress);\n } */\n\n this.setScrollTop(newScrollTop, useReflow);\n\n /* if(DEBUG) {\n this.log('performHistoryResult: have set up scrollTop:', newScrollTop, container.scrollTop, container.scrollHeight, this.isHeavyAnimationInProgress);\n } */\n }\n}\n\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.ScrollSaver = ScrollSaver);\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport Scrollable from '../components/scrollable';\nimport safeAssign from './object/safeAssign';\n\nexport default class ScrollableLoader {\n public loading = false;\n private scrollable: Scrollable;\n private getPromise: () => Promise<boolean>;\n private promise: Promise<any>;\n private loaded = false;\n\n constructor(options: {\n scrollable: ScrollableLoader['scrollable'],\n getPromise: ScrollableLoader['getPromise']\n }) {\n safeAssign(this, options);\n\n options.scrollable.onScrolledBottom = () => {\n this.load();\n };\n }\n\n public load() {\n if(this.loaded) {\n return Promise.resolve();\n }\n\n if(this.loading) {\n return this.promise;\n }\n\n this.loading = true;\n this.promise = this.getPromise().then((done) => {\n this.loading = false;\n this.promise = undefined;\n\n if(done) {\n this.loaded = true;\n this.scrollable.onScrolledBottom = null;\n } else {\n this.scrollable.checkForTriggers();\n }\n }, () => {\n this.promise = undefined;\n this.loading = false;\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MediaSearchContext} from '../components/appMediaPlaybackController';\nimport type {SearchSuperContext} from '../components/appSearchSuper.';\nimport type {Message} from '../layer';\nimport type {MessagesStorageKey, MyMessage} from '../lib/appManagers/appMessagesManager';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport incrementMessageId from '../lib/appManagers/utils/messageId/incrementMessageId';\nimport rootScope from '../lib/rootScope';\nimport forEachReverse from './array/forEachReverse';\nimport filterChatPhotosMessages from './filterChatPhotosMessages';\nimport ListLoader, {ListLoaderOptions} from './listLoader';\n\nexport default class SearchListLoader<Item extends {mid: number, peerId: PeerId}> extends ListLoader<Item, Message.message> {\n public searchContext: MediaSearchContext;\n public onEmptied: () => void;\n\n private otherSideLoader: SearchListLoader<Item>;\n private managers: AppManagers;\n\n constructor(options: Omit<ListLoaderOptions<Item, Message.message>, 'loadMore'> & {\n onEmptied?: () => void,\n isInner?: boolean,\n managers?: AppManagers\n } = {}) {\n super({\n ...options,\n loadMore: (anchor, older, loadCount) => {\n const backLimit = older ? 0 : loadCount;\n let maxId = anchor?.mid;\n\n if(maxId === undefined) maxId = this.searchContext.maxId;\n if(!older) maxId = incrementMessageId(maxId, 1);\n\n return this.managers.appMessagesManager.getSearch({\n ...this.searchContext,\n peerId: this.searchContext.peerId || anchor?.peerId,\n maxId,\n limit: backLimit ? 0 : loadCount,\n backLimit\n }).then((value) => {\n /* if(DEBUG) {\n this.log('loaded more media by maxId:', maxId, value, older, this.reverse);\n } */\n\n if(this.searchContext.inputFilter._ === 'inputMessagesFilterChatPhotos') {\n filterChatPhotosMessages(value);\n }\n\n if(value.next_rate) {\n this.searchContext.nextRate = value.next_rate;\n }\n\n return {count: value.count, items: value.history};\n });\n },\n processItem: async(message) => {\n const filtered = await this.filterMids([message.mid]);\n if(!filtered.length) {\n return;\n }\n\n return options.processItem(message);\n }\n });\n\n this.managers ??= rootScope.managers;\n rootScope.addEventListener('history_delete', this.onHistoryDelete);\n rootScope.addEventListener('history_multiappend', this.onHistoryMultiappend);\n rootScope.addEventListener('message_sent', this.onMessageSent);\n\n if(!options.isInner) {\n this.otherSideLoader = new SearchListLoader({\n ...options,\n isInner: true\n });\n\n // this.otherSideLoader.onLoadedMore = () => {\n\n // };\n }\n }\n\n protected async filterMids(mids: number[]) {\n const storageKey: MessagesStorageKey = `${this.searchContext.peerId}_${this.searchContext.isScheduled ? 'scheduled' : 'history'}`;\n const filtered = (await this.managers.appMessagesManager.filterMessagesByInputFilterFromStorage(this.searchContext.inputFilter._, mids, storageKey, mids.length)) as Message.message[];\n return filtered;\n }\n\n protected onHistoryDelete = ({peerId, msgs}: {peerId: PeerId, msgs: Set<number>}) => {\n const shouldBeDeleted = (item: Item) => item.peerId === peerId && msgs.has(item.mid);\n const filter = (item: Item, idx: number, arr: Item[]) => {\n if(shouldBeDeleted(item)) {\n arr.splice(idx, 1);\n }\n };\n\n forEachReverse(this.previous, filter);\n forEachReverse(this.next, filter);\n\n if(this.current && shouldBeDeleted(this.current)) {\n this.current = undefined;\n /* if(this.go(1)) {\n this.previous.splice(this.previous.length - 1, 1);\n } else if(this.go(-1)) {\n this.next.splice(0, 1);\n } else */if(this.onEmptied) {\n this.onEmptied();\n }\n }\n };\n\n protected onHistoryMultiappend = async(message: Message.message | Message.messageService) => {\n if(this.searchContext.folderId !== undefined) {\n return;\n }\n\n // because it's reversed\n if(!this.loadedAllUp || this.loadPromiseUp) {\n return;\n }\n\n if(message.peerId !== this.searchContext.peerId) {\n return;\n }\n\n const filtered = await this.filterMids([message.mid]);\n const targets = (await Promise.all(filtered.map((message) => this.processItem(message)))).filter(Boolean);\n if(targets.length) {\n /* const {previous, current, next} = this;\n const targets = previous.concat(current, next);\n const currentIdx = targets.length;\n const mid = targets[0].mid;\n let i = 0, length = targets.length;\n for(; i < length; ++i) {\n const target = targets[i];\n if(!target || mid < target.mid) {\n break;\n }\n }\n\n if(i < currentIdx) previous.push(...targets);\n else next. */\n\n if(!this.current) {\n this.previous.push(...targets);\n } else {\n this.next.push(...targets);\n }\n }\n };\n\n protected onMessageSent = ({message}: {message: MyMessage}) => {\n this.onHistoryMultiappend(message);\n };\n\n public setSearchContext(context: SearchSuperContext) {\n this.searchContext = context;\n\n if(this.searchContext.folderId !== undefined) {\n this.loadedAllUp = true;\n\n if(this.searchContext.nextRate === undefined) {\n this.loadedAllDown = true;\n }\n }\n\n if(this.searchContext.inputFilter._ === 'inputMessagesFilterChatPhotos') {\n this.loadedAllUp = true;\n }\n\n if(this.searchContext.useSearch === false) {\n this.loadedAllDown = this.loadedAllUp = true;\n }\n\n if(this.otherSideLoader) {\n this.otherSideLoader.setSearchContext(context);\n }\n }\n\n public reset() {\n super.reset();\n this.searchContext = undefined;\n\n if(this.otherSideLoader) {\n this.otherSideLoader.reset();\n }\n }\n\n public getPrevious(withOtherSide?: boolean) {\n let previous = this.previous;\n\n if(this.otherSideLoader && withOtherSide) {\n previous = previous.concat(this.otherSideLoader.previous);\n }\n\n return previous;\n }\n\n public getNext(withOtherSide?: boolean) {\n let next = this.next;\n\n if(this.otherSideLoader && withOtherSide) {\n next = next.concat(this.otherSideLoader.next);\n }\n\n return next;\n }\n\n public getCurrent() {\n return this.current || this.otherSideLoader?.current;\n }\n\n private goToOtherEnd(length: number) {\n if(length > 0) return this.go(-this.previous.length);\n else return this.go(this.next.length);\n }\n\n public goRound(length: number, dispatchJump?: boolean) {\n let ret: ReturnType<SearchListLoader<Item>['goUnsafe']>;\n\n if(this.otherSideLoader?.current) {\n ret = this.otherSideLoader.goUnsafe(length, dispatchJump);\n if(ret.item) {\n return ret.item;\n }\n\n length = ret.leftLength;\n if(!(length > 0 ? this.otherSideLoader.next : this.otherSideLoader.previous).length) {\n const loaded = length > 0 ? this.otherSideLoader.loadedAllUp : this.otherSideLoader.loadedAllDown;\n if(!loaded) { // do not reset anything until it's loaded\n return;\n }\n\n // if other side is loaded too will start from its begin\n if((length > 0 && (this.otherSideLoader.searchContext.maxId === 1 || this.otherSideLoader.loadedAllDown)) ||\n (length < 0 && (this.otherSideLoader.searchContext.maxId === 0 || this.otherSideLoader.loadedAllUp))) {\n return this.otherSideLoader.goToOtherEnd(length);\n }\n\n this.otherSideLoader.unsetCurrent(length > 0);\n }\n }\n\n ret = this.goUnsafe(length, dispatchJump);\n if(!ret.item) {\n if(this.loadedAllUp && this.loadedAllDown) { // just use the same loader if the list is too short\n return this.goToOtherEnd(length);\n } else if(this.otherSideLoader) {\n length = ret.leftLength;\n ret = this.otherSideLoader.goUnsafe(length, dispatchJump);\n\n if(ret.item) {\n this.unsetCurrent(length > 0);\n }\n }\n }\n\n return ret?.item;\n }\n\n // public setTargets(previous: Item[], next: Item[], reverse: boolean) {\n // super.setTargets(previous, next, reverse);\n // }\n\n protected setLoaded(down: boolean, value: boolean) {\n const changed = super.setLoaded(down, value);\n\n if(changed &&\n this.otherSideLoader &&\n value &&\n this.searchContext?.useSearch !== false/* &&\n (this.reverse ? this.loadedAllUp : this.loadedAllDown) */) {\n const reverse = this.loadedAllUp;\n this.otherSideLoader.setSearchContext({\n ...this.searchContext,\n maxId: reverse ? 1 : 0\n });\n\n // these 'reverse' are different, not a mistake here.\n this.otherSideLoader.reverse = this.reverse;\n this.otherSideLoader.setLoaded(reverse, true);\n this.otherSideLoader.load(!reverse);\n }\n\n return changed;\n }\n\n public cleanup() {\n this.reset();\n rootScope.removeEventListener('history_delete', this.onHistoryDelete);\n rootScope.removeEventListener('history_multiappend', this.onHistoryMultiappend);\n rootScope.removeEventListener('message_sent', this.onMessageSent);\n this.onEmptied = undefined;\n\n if(this.otherSideLoader) {\n this.otherSideLoader.cleanup();\n this.otherSideLoader = undefined;\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport generateMessageId from './generateMessageId';\nimport getServerMessageId from './getServerMessageId';\n\nexport default function incrementMessageId(messageId: number, increment: number) {\n return generateMessageId(getServerMessageId(messageId) + increment);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {fastRaf} from './schedulers';\nimport deferredPromise, {CancellablePromise} from './cancellablePromise';\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport isInDOM from './dom/isInDOM';\n\nclass SequentialDom {\n private promises: Partial<{\n read: CancellablePromise<void>,\n write: CancellablePromise<void>\n }> = {};\n private raf = fastRaf.bind(null);\n private scheduled = false;\n\n private do(kind: keyof SequentialDom['promises'], callback?: VoidFunction) {\n let promise = this.promises[kind];\n if(!promise) {\n this.scheduleFlush();\n promise = this.promises[kind] = deferredPromise<void>();\n }\n\n if(callback !== undefined) {\n promise.then(() => callback());\n }\n\n return promise;\n }\n\n public measure(callback?: VoidFunction) {\n return this.do('read', callback);\n }\n\n public mutate(callback?: VoidFunction) {\n return this.do('write', callback);\n }\n\n /**\n * Will fire instantly if element is not connected\n * @param element\n * @param callback\n */\n public mutateElement(element: HTMLElement, callback?: VoidFunction) {\n const isConnected = isInDOM(element);\n const promise = isConnected ? this.mutate() : Promise.resolve();\n\n if(callback !== undefined) {\n if(!isConnected) {\n callback();\n } else {\n promise.then(() => callback());\n }\n }\n\n return promise;\n }\n\n private scheduleFlush() {\n if(!this.scheduled) {\n this.scheduled = true;\n\n this.raf(() => {\n this.promises.read && this.promises.read.resolve();\n this.promises.write && this.promises.write.resolve();\n\n this.scheduled = false;\n this.promises = {};\n });\n }\n }\n}\n\nconst sequentialDom = new SequentialDom();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.sequentialDom = sequentialDom);\nexport default sequentialDom;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {PhotoSize, WebDocument} from '../layer';\nimport {REPLIES_HIDDEN_CHANNEL_ID} from '../lib/mtproto/mtproto_config';\nimport {MyDocument} from '../lib/appManagers/appDocsManager';\nimport {MyPhoto} from '../lib/appManagers/appPhotosManager';\nimport choosePhotoSize from '../lib/appManagers/utils/photos/choosePhotoSize';\nimport {MediaSize, makeMediaSize} from './mediaSize';\nimport isWebDocument from '../lib/appManagers/utils/webDocs/isWebDocument';\n\nexport default function setAttachmentSize(\n photo: MyPhoto | MyDocument | WebDocument,\n element: HTMLElement | SVGForeignObjectElement,\n boxWidth: number,\n boxHeight: number,\n noZoom = true,\n message?: any,\n pushDocumentSize?: boolean,\n photoSize?: ReturnType<typeof choosePhotoSize>\n) {\n const _isWebDocument = isWebDocument(photo);\n // if(_isWebDocument && pushDocumentSize === undefined) {\n // pushDocumentSize = true;\n // }\n\n if(!photoSize) {\n photoSize = choosePhotoSize(photo, boxWidth, boxHeight, undefined, pushDocumentSize);\n }\n // console.log('setAttachmentSize', photo, photo.sizes[0].bytes, div);\n\n let size: MediaSize;\n const isDocument = photo._ === 'document';\n if(isDocument || _isWebDocument) {\n size = makeMediaSize(photo.w || (photoSize as PhotoSize.photoSize).w || 512, photo.h || (photoSize as PhotoSize.photoSize).h || 512);\n } else {\n size = makeMediaSize((photoSize as PhotoSize.photoSize).w || 100, (photoSize as PhotoSize.photoSize).h || 100);\n }\n\n let boxSize = makeMediaSize(boxWidth, boxHeight);\n\n boxSize = size = size.aspect(boxSize, noZoom);\n\n let isFit = true;\n\n if(!isDocument || ['video', 'gif'].includes(photo.type) || _isWebDocument) {\n if(boxSize.width < 200 && boxSize.height < 200) { // make at least one side this big\n boxSize = size = size.aspectCovered(makeMediaSize(200, 200));\n }\n\n if(message &&\n (message.message ||\n message.reply_to_mid ||\n message.media.webpage ||\n (message.replies && message.replies.pFlags.comments && message.replies.channel_id.toChatId() !== REPLIES_HIDDEN_CHANNEL_ID)\n )\n ) { // make sure that bubble block is human-readable\n if(boxSize.width < 320) {\n boxSize = makeMediaSize(320, boxSize.height);\n isFit = false;\n }\n }\n\n if(isFit && boxSize.width < 120 && message) { // if image is too narrow\n boxSize = makeMediaSize(120, boxSize.height);\n isFit = false;\n }\n }\n\n // if(element instanceof SVGForeignObjectElement) {\n // element.setAttributeNS(null, 'width', '' + w);\n // element.setAttributeNS(null, 'height', '' + h);\n\n // //console.log('set dimensions to svg element:', element, w, h);\n // } else {\n element.style.width = boxSize.width + 'px';\n element.style.height = boxSize.height + 'px';\n // }\n\n return {photoSize, size, isFit};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {logger} from '../lib/logger';\nimport insertInDescendSortedArray from './array/insertInDescendSortedArray';\nimport {getMiddleware, MiddlewareHelper} from './middleware';\nimport middlewarePromise from './middlewarePromise';\nimport safeAssign from './object/safeAssign';\nimport pause from './schedulers/pause';\n\nexport type SortedElementBase<T = any> = {\n id: T,\n index: number\n};\n\nlet id = 0;\n\nexport class BatchProcessor<Item extends any = any> {\n protected queue: Promise<Item>[];\n protected promise: Promise<void>;\n\n protected middlewareHelper: MiddlewareHelper;\n protected log: ReturnType<typeof logger>;\n\n protected process: (batch: Item[], m: ReturnType<typeof middlewarePromise>, log: BatchProcessor['log']) => Promise<any>;\n protected possibleError: any;\n\n constructor(options: {\n log?: BatchProcessor['log'],\n // middleware: MiddlewareHelper,\n process: BatchProcessor<Item>['process'],\n possibleError?: BatchProcessor['possibleError']\n }) {\n safeAssign(this, options);\n\n this.queue = [];\n this.middlewareHelper ??= getMiddleware();\n\n const prefix = 'BATCH-PROCESSOR-' + ++id;\n if(this.log) {\n this.log = this.log.bindPrefix(prefix);\n } else {\n this.log = logger(prefix);\n }\n }\n\n public get queuePromise() {\n return this.promise;\n }\n\n public clear() {\n this.log('clear');\n this.queue.length = 0;\n this.promise = undefined;\n this.middlewareHelper.clean();\n }\n\n public addToQueue(item: BatchProcessor<Item>['queue'][0]) {\n this.queue.push(item);\n return this.setQueue();\n }\n\n protected setQueue() {\n if(!this.queue.length) {\n return Promise.resolve();\n }\n\n if(this.promise) {\n return this.promise;\n }\n\n const middleware = this.middlewareHelper.get();\n const log = this.log.bindPrefix('queue');\n const m = middlewarePromise(middleware, this.possibleError);\n\n const processQueue = async(): Promise<void> => {\n log('start', this.queue.length);\n\n const queue = this.queue.splice(0, this.queue.length);\n\n const perf = performance.now();\n const promises = queue.map((promise) => {\n promise.then((details) => {\n log('render item time', performance.now() - perf, details);\n });\n\n return promise;\n });\n\n const renderedQueue = await m(Promise.all(promises));\n await m(this.process(renderedQueue, m, log));\n\n log('queue rendered');\n\n if(this.queue.length) {\n log('have new items to render');\n return processQueue();\n } else {\n log('end');\n }\n };\n\n log('setting pause');\n const promise = this.promise = m(pause(0))\n .then(\n () => processQueue().catch((err: ApiError) => {\n if(err !== this.possibleError) {\n log.error('process queue error', err);\n }\n\n throw err;\n }),\n (err) => {\n log('pause has been cleared');\n throw err;\n }\n )\n .finally(() => {\n if(this.promise === promise) {\n this.promise = undefined;\n }\n });\n\n return promise;\n }\n}\n\nexport default class SortedList<SortedElement extends SortedElementBase, SortedElementId = SortedElement['id']> {\n protected elements: Map<SortedElementId, SortedElement>;\n protected sorted: Array<SortedElement>;\n\n protected getIndex: (element: SortedElement) => PromiseLike<number> | number;\n protected onDelete: (element: SortedElement) => void;\n protected onUpdate: (element: SortedElement) => void;\n protected onSort: (element: SortedElement, idx: number) => void;\n protected onElementCreate: (base: SortedElementBase) => PromiseLike<SortedElement> | SortedElement;\n\n protected updateElementWith = (callback: () => void) => callback();\n protected updateListWith = (callback: (canUpdate: boolean | undefined) => void) => callback(true);\n\n protected middleware: MiddlewareHelper;\n\n protected batchProcessor: BatchProcessor<SortedElement>;\n\n protected log: ReturnType<typeof logger>;\n\n constructor(options: {\n getIndex: SortedList<SortedElement>['getIndex'],\n onDelete?: SortedList<SortedElement>['onDelete'],\n onUpdate?: SortedList<SortedElement>['onUpdate'],\n onSort?: SortedList<SortedElement>['onSort'],\n onElementCreate: SortedList<SortedElement>['onElementCreate'],\n\n updateElementWith?: SortedList<SortedElement>['updateElementWith'],\n updateListWith?: SortedList<SortedElement>['updateListWith'],\n\n log?: SortedList<SortedElement>['log']\n }) {\n safeAssign(this, options);\n\n this.elements = new Map();\n this.sorted = [];\n this.middleware = getMiddleware();\n\n this.batchProcessor = new BatchProcessor<SortedElement>({\n log: this.log,\n process: async(batch, m, log) => {\n // const elements = await Promise.all(batch.map((element) => this.onElementCreate(element)));\n const elements = batch;\n const promises = elements.map((element) => this.update(element.id, element));\n await m(Promise.all(promises));\n }\n });\n }\n\n public clear() {\n this.batchProcessor.clear();\n this.middleware.clean();\n this.elements.clear();\n this.sorted.length = 0;\n }\n\n protected _updateList() {\n this.elements.forEach((element) => {\n this.update(element.id);\n });\n\n if(this.onSort) {\n this.sorted.forEach((element, idx) => {\n this.onSort(element, idx);\n });\n }\n }\n\n public updateList(callback?: (updated: boolean) => void) {\n const middleware = this.middleware.get();\n this.updateListWith((canUpdate) => {\n if(!middleware() || (canUpdate !== undefined && !canUpdate)) {\n callback?.(false);\n return;\n }\n\n this._updateList();\n\n callback?.(true);\n });\n }\n\n public has(id: SortedElementId) {\n return this.elements.has(id);\n }\n\n public get(id: SortedElementId) {\n return this.elements.get(id);\n }\n\n public getAll() {\n return this.elements;\n }\n\n public async add(id: SortedElementId) {\n const element = this.get(id);\n if(element) {\n return;\n // return element;\n }\n\n const base: SortedElementBase = {\n id,\n index: 0\n };\n\n this.elements.set(id, base as SortedElement);\n const createPromise = Promise.resolve(this.onElementCreate(base));\n return this.batchProcessor.addToQueue(createPromise);\n\n // return element;\n }\n\n public delete(id: SortedElementId, noScheduler?: boolean) {\n const element = this.elements.get(id);\n if(!element) {\n return false;\n }\n\n this.elements.delete(id);\n\n const idx = this.sorted.indexOf(element);\n if(idx !== -1) {\n this.sorted.splice(idx, 1);\n }\n\n if(this.onDelete) {\n if(noScheduler) {\n this.onDelete(element);\n } else {\n const middleware = this.middleware.get();\n this.updateElementWith(() => {\n if(!middleware()) {\n return;\n }\n\n this.onDelete(element);\n });\n }\n }\n\n return true;\n }\n\n public async update(id: SortedElementId, element = this.get(id)) {\n if(!element) {\n return;\n }\n\n element.index = await this.getIndex(element);\n if(this.get(id) !== element) {\n return;\n }\n\n this.onUpdate?.(element);\n\n const idx = insertInDescendSortedArray(this.sorted, element, 'index');\n this.onSort(element, idx);\n }\n}\n","const BOM = '';\n// const BOM = 'K';\nexport default BOM;\n","export default function encodeEntities(value: string) {\n return value.replace(/&/g, '&amp;').replace(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g, (value) => {\n const hi = value.charCodeAt(0);\n const low = value.charCodeAt(1);\n return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';\n }).replace(/([^\\#-~| |!])/g, (value) => { // non-alphanumeric\n return '&#' + value.charCodeAt(0) + ';';\n }).replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n","// credits to https://github.com/sindresorhus/escape-string-regexp/blob/master/index.js\nexport default function escapeRegExp(str: string) {\n return str\n .replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&')\n .replace(/-/g, '\\\\x2d');\n}\n","export default function limitSymbols(str: string, length: number, limitFrom = length + 10) {\n str = str.trim();\n if(str.length > limitFrom) {\n str = str.slice(0, length)/* .replace(/\\s*$/, '') */ + '...';\n }\n\n return str;\n}\n","const NBSP = '';\nexport default NBSP;\n","export default function toHHMMSS(str: string | number, leadZero = false) {\n const sec_num = parseInt(str + '', 10);\n const hours = Math.floor(sec_num / 3600);\n let minutes: any = Math.floor((sec_num - (hours * 3600)) / 60);\n let seconds: any = sec_num - (hours * 3600) - (minutes * 60);\n\n if(hours) leadZero = true;\n if(minutes < 10) minutes = leadZero ? '0' + minutes : minutes;\n if(seconds < 10) seconds = '0' + seconds;\n return (hours ? /* ('0' + hours).slice(-2) */hours + ':' : '') + minutes + ':' + seconds;\n}\n","export default function textToSvgURL(text: string) {\n const blob = new Blob([text], {type: 'image/svg+xml;charset=utf-8'});\n\n // * because iOS Safari doesn't want to eat objectURL\n return new Promise<string>((resolve) => {\n const reader = new FileReader();\n reader.onload = (e) => {\n resolve(e.target.result as string);\n };\n reader.readAsDataURL(blob);\n });\n // return URL.createObjectURL(blob);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport {IS_WORKER} from './context';\n\nexport class WindowSize {\n public width: number;\n public height: number;\n\n constructor() {\n if(IS_WORKER) {\n return;\n }\n\n const w = 'visualViewport' in window ? window.visualViewport : window;\n const set = () => {\n this.width = w.width || (w as any as Window).innerWidth;\n this.height = w.height || (w as any as Window).innerHeight;\n };\n w.addEventListener('resize', set);\n set();\n }\n}\n\nconst windowSize = new WindowSize();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.windowSize = windowSize);\nexport default windowSize;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\n// * Jolly Cobra's useHeavyAnimationCheck.ts, patched\n\nimport {AnyToVoidFunction} from '../types';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport deferredPromise, {CancellablePromise} from '../helpers/cancellablePromise';\nimport DEBUG from '../config/debug';\nimport pause from '../helpers/schedulers/pause';\nimport EventListenerBase from '../helpers/eventListenerBase';\n\nconst eventListener = new EventListenerBase<{\n start: () => void,\n end: () => void\n}>();\nconst ANIMATION_START_EVENT = 'start';\nconst ANIMATION_END_EVENT = 'end';\n\nlet isAnimating = false;\nlet heavyAnimationPromise: CancellablePromise<void> = deferredPromise<void>();\nlet promisesInQueue = 0;\n\nheavyAnimationPromise.resolve();\n\nconst log = console.log.bind(console.log, '[HEAVY-ANIMATION]:');\n\nexport function dispatchHeavyAnimationEvent(promise: Promise<any>, timeout?: number) {\n if(!isAnimating) {\n heavyAnimationPromise = deferredPromise<void>();\n eventListener.dispatchEvent(ANIMATION_START_EVENT);\n isAnimating = true;\n DEBUG && log('start');\n }\n\n ++promisesInQueue;\n DEBUG && log('attach promise, length:', promisesInQueue, timeout);\n\n const promises = [\n timeout !== undefined ? pause(timeout) : undefined,\n promise.finally(() => {})\n ].filter(Boolean);\n\n const perf = performance.now();\n const _heavyAnimationPromise = heavyAnimationPromise;\n Promise.race(promises).then(() => {\n if(heavyAnimationPromise !== _heavyAnimationPromise || heavyAnimationPromise.isFulfilled) { // interrupted\n return;\n }\n\n --promisesInQueue;\n DEBUG && log('promise end, length:', promisesInQueue, performance.now() - perf);\n if(promisesInQueue <= 0) {\n onHeavyAnimationEnd();\n }\n });\n\n return heavyAnimationPromise;\n}\n\n(window as any).dispatchHeavyAnimationEvent = dispatchHeavyAnimationEvent;\n\nfunction onHeavyAnimationEnd() {\n if(heavyAnimationPromise.isFulfilled) {\n return;\n }\n\n isAnimating = false;\n promisesInQueue = 0;\n eventListener.dispatchEvent(ANIMATION_END_EVENT);\n heavyAnimationPromise.resolve();\n\n DEBUG && log('end');\n}\n\nexport function interruptHeavyAnimation() {\n onHeavyAnimationEnd();\n}\n\nexport function getHeavyAnimationPromise() {\n return heavyAnimationPromise;\n}\n\nexport default function(\n handleAnimationStart: AnyToVoidFunction,\n handleAnimationEnd: AnyToVoidFunction,\n listenerSetter?: ListenerSetter\n) {\n // useEffect(() => {\n if(isAnimating) {\n handleAnimationStart();\n }\n\n const add = listenerSetter ? listenerSetter.add(eventListener) : eventListener.addEventListener.bind(eventListener);\n const remove = listenerSetter ? listenerSetter.removeManual.bind(listenerSetter, eventListener) : eventListener.removeEventListener.bind(eventListener);\n add(ANIMATION_START_EVENT, handleAnimationStart);\n add(ANIMATION_END_EVENT, handleAnimationEnd);\n\n return () => {\n remove(ANIMATION_END_EVENT, handleAnimationEnd);\n remove(ANIMATION_START_EVENT, handleAnimationStart);\n };\n // }, [handleAnimationEnd, handleAnimationStart]);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {Dialog} from '../lib/appManagers/appMessagesManager';\nimport type {ForumTopic} from '../layer';\nimport appDialogsManager, {DIALOG_LIST_ELEMENT_TAG} from '../lib/appManagers/appDialogsManager';\nimport rootScope from '../lib/rootScope';\nimport {ButtonMenuItemOptionsVerifiable, ButtonMenuSync} from './buttonMenu';\nimport PopupDeleteDialog from './popups/deleteDialog';\nimport {i18n, LangPackKey, _i18n} from '../lib/langPack';\nimport findUpTag from '../helpers/dom/findUpTag';\nimport {toastNew} from './toast';\nimport PopupMute from './popups/mute';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport {GENERAL_TOPIC_ID} from '../lib/mtproto/mtproto_config';\nimport showLimitPopup from './popups/limit';\nimport createContextMenu from '../helpers/dom/createContextMenu';\nimport PopupElement from './popups';\n\nexport default class DialogsContextMenu {\n private buttons: ButtonMenuItemOptionsVerifiable[];\n\n private peerId: PeerId;\n private filterId: number;\n private threadId: number;\n private dialog: Dialog | ForumTopic.forumTopic;\n private canManageTopics: boolean;\n private li: HTMLElement;\n\n constructor(private managers: AppManagers) {\n\n }\n\n public attach(element: HTMLElement) {\n createContextMenu({\n listenTo: element,\n buttons: this.getButtons(),\n appendTo: document.getElementById('page-chats'),\n onOpen: async(li) => {\n this.li = li;\n li.classList.add('menu-open');\n this.peerId = li.dataset.peerId.toPeerId();\n this.threadId = +li.dataset.threadId || undefined;\n this.dialog = await this.managers.dialogsStorage.getDialogOrTopic(this.peerId, this.threadId);\n this.filterId = this.threadId ? undefined : appDialogsManager.filterId;\n this.canManageTopics = this.threadId ? await this.managers.appChatsManager.hasRights(this.peerId.toChatId(), 'manage_topics') : undefined;\n },\n onBeforeOpen: async() => {\n // delete button\n const langPackKey: LangPackKey = this.threadId ? 'Delete' : await this.managers.appPeersManager.getDeleteButtonText(this.peerId);\n const lastButton = this.buttons[this.buttons.length - 1];\n if(lastButton?.element) {\n lastButton.element.lastChild.replaceWith(i18n(langPackKey));\n }\n },\n onClose: () => {\n this.li.classList.remove('menu-open');\n this.li = this.peerId = this.dialog = this.filterId = this.threadId = this.canManageTopics = undefined;\n },\n findElement: (e) => {\n return findUpTag(e.target, DIALOG_LIST_ELEMENT_TAG);\n }\n });\n }\n\n private getButtons() {\n return this.buttons ??= [{\n icon: 'unread',\n text: 'MarkAsUnread',\n onClick: this.onUnreadClick,\n verify: async() => !this.threadId && !(await this.managers.appMessagesManager.isDialogUnread(this.dialog))\n }, {\n icon: 'readchats',\n text: 'MarkAsRead',\n onClick: this.onUnreadClick,\n verify: () => this.managers.appMessagesManager.isDialogUnread(this.dialog)\n }, {\n icon: 'pin',\n text: 'ChatList.Context.Pin',\n onClick: this.onPinClick,\n verify: async() => {\n if(this.threadId && !this.canManageTopics) {\n return false;\n }\n\n const isPinned = this.filterId !== undefined && this.filterId > 1 ?\n (await this.managers.appMessagesManager.getFilter(this.filterId)).pinnedPeerIds.includes(this.dialog.peerId) :\n !!this.dialog.pFlags?.pinned;\n return !isPinned;\n }\n }, {\n icon: 'unpin',\n text: 'ChatList.Context.Unpin',\n onClick: this.onPinClick,\n verify: async() => {\n if(this.threadId && !this.canManageTopics) {\n return false;\n }\n\n const isPinned = this.filterId !== undefined && this.filterId > 1 ?\n (await this.managers.appMessagesManager.getFilter(this.filterId)).pinnedPeerIds.includes(this.dialog.peerId) :\n !!this.dialog.pFlags?.pinned;\n return isPinned;\n }\n }, {\n icon: 'mute',\n text: 'ChatList.Context.Mute',\n onClick: this.onMuteClick,\n verify: async() => {\n return this.peerId !== rootScope.myId && !(await this.managers.appNotificationsManager.isPeerLocalMuted({peerId: this.dialog.peerId, threadId: this.threadId}));\n }\n }, {\n icon: 'unmute',\n text: 'ChatList.Context.Unmute',\n onClick: this.onUnmuteClick,\n verify: async() => {\n return this.peerId !== rootScope.myId && (await this.managers.appNotificationsManager.isPeerLocalMuted({peerId: this.dialog.peerId, threadId: this.threadId}));\n }\n }, {\n icon: 'archive',\n text: 'Archive',\n onClick: this.onArchiveClick,\n verify: () => this.filterId === 0 && this.peerId !== rootScope.myId\n }, {\n icon: 'unarchive',\n text: 'Unarchive',\n onClick: this.onArchiveClick,\n verify: () => this.filterId === 1 && this.peerId !== rootScope.myId\n }, {\n icon: 'hide',\n text: 'Hide',\n onClick: this.onHideTopicClick,\n verify: () => {\n return this.canManageTopics && (this.dialog as ForumTopic.forumTopic).id === GENERAL_TOPIC_ID;\n }\n }, {\n icon: 'lock',\n text: 'CloseTopic',\n onClick: this.onToggleTopicClick,\n verify: () => {\n return this.canManageTopics && !(this.dialog as ForumTopic.forumTopic).pFlags.closed;\n }\n }, {\n icon: 'lockoff',\n text: 'RestartTopic',\n onClick: this.onToggleTopicClick,\n verify: () => {\n return this.canManageTopics && !!(this.dialog as ForumTopic.forumTopic).pFlags.closed;\n }\n }, {\n icon: 'delete danger',\n text: 'Delete',\n onClick: this.onDeleteClick,\n verify: () => {\n if(this.threadId) {\n if(!this.canManageTopics) {\n return false;\n }\n\n return (this.dialog as ForumTopic.forumTopic).id !== GENERAL_TOPIC_ID;\n }\n\n return true;\n }\n }];\n }\n\n private onArchiveClick = async() => {\n const dialog = await this.managers.appMessagesManager.getDialogOnly(this.peerId);\n if(dialog) {\n this.managers.appMessagesManager.editPeerFolders([dialog.peerId], +!dialog.folder_id);\n }\n };\n\n private onHideTopicClick = () => {\n this.managers.appChatsManager.editForumTopic({\n chatId: this.peerId.toChatId(),\n topicId: this.threadId,\n hidden: true\n });\n };\n\n private onToggleTopicClick = () => {\n this.managers.appChatsManager.editForumTopic({\n chatId: this.peerId.toChatId(),\n topicId: this.threadId,\n closed: !(this.dialog as ForumTopic.forumTopic).pFlags.closed\n });\n };\n\n private onPinClick = () => {\n const {peerId, filterId, threadId} = this;\n this.managers.appMessagesManager.toggleDialogPin({\n peerId,\n filterId,\n topicId: threadId\n }).catch(async(err: ApiError) => {\n if(err.type === 'PINNED_DIALOGS_TOO_MUCH' || err.type === 'PINNED_TOO_MUCH') {\n if(threadId) {\n this.managers.apiManager.getLimit('topicPin').then((limit) => {\n toastNew({langPackKey: 'LimitReachedPinnedTopics', langPackArguments: [limit]});\n });\n } else if(filterId >= 1) {\n toastNew({langPackKey: 'PinFolderLimitReached'});\n } else {\n showLimitPopup('pin');\n }\n }\n });\n };\n\n private onUnmuteClick = () => {\n this.managers.appMessagesManager.togglePeerMute({peerId: this.peerId, mute: false, threadId: this.threadId});\n };\n\n private onMuteClick = () => {\n PopupElement.createPopup(PopupMute, this.peerId, this.threadId);\n };\n\n private onUnreadClick = async() => {\n const {peerId, dialog} = this;\n if(dialog.unread_count) {\n this.managers.appMessagesManager.readHistory(peerId, dialog.top_message, this.threadId);\n\n if(!this.threadId) {\n this.managers.appMessagesManager.markDialogUnread(peerId, true);\n }\n } else if(!this.threadId) {\n this.managers.appMessagesManager.markDialogUnread(peerId);\n }\n };\n\n private onDeleteClick = () => {\n PopupElement.createPopup(PopupDeleteDialog, this.peerId, undefined, undefined, this.threadId);\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport App from '../config/app';\nimport DEBUG from '../config/debug';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport {LangPackKey, i18n} from '../lib/langPack';\nimport {logger} from '../lib/logger';\nimport rootScope from '../lib/rootScope';\nimport Button from './button';\nimport ProgressivePreloader from './preloader';\nimport SetTransition from './singleTransition';\nimport sessionStorage from '../lib/sessionStorage';\nimport {ConnectionStatus} from '../lib/mtproto/connectionStatus';\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport singleInstance from '../lib/mtproto/singleInstance';\n\nexport default class ConnectionStatusComponent {\n public static CHANGE_STATE_DELAY = 1000;\n\n private statusContainer: HTMLElement;\n private statusEl: HTMLElement;\n private statusPreloader: ProgressivePreloader;\n\n private currentLangPackKey: LangPackKey;\n\n private hadConnect = false;\n private retryAt: number;\n private connecting = false;\n private timedOut = false;\n private updating = false;\n\n private log: ReturnType<typeof logger>;\n\n private setFirstConnectionTimeout: number;\n private setStateTimeout: number;\n\n constructor(private managers: AppManagers, chatsContainer: HTMLElement) {\n this.log = logger('CS', undefined, undefined);\n\n this.statusContainer = document.createElement('div');\n this.statusContainer.classList.add('connection-status'/* , 'hide' */);\n\n this.statusEl = Button('btn-primary bg-warning connection-status-button', {noRipple: true});\n this.statusPreloader = new ProgressivePreloader({cancelable: false});\n this.statusPreloader.constructContainer({color: 'transparent', bold: true});\n this.statusContainer.append(this.statusEl);\n\n chatsContainer.prepend(this.statusContainer);\n\n rootScope.addEventListener('connection_status_change', (status) => {\n // console.log(status);\n\n this.setConnectionStatus();\n });\n\n rootScope.addEventListener('state_synchronizing', (channelId) => {\n if(!channelId) {\n this.updating = true;\n DEBUG && this.log('updating', this.updating);\n this.setState();\n }\n });\n\n rootScope.addEventListener('state_synchronized', (channelId) => {\n DEBUG && this.log('state_synchronized', channelId);\n if(!channelId) {\n this.updating = false;\n DEBUG && this.log('updating', this.updating);\n this.setState();\n }\n });\n\n this.setFirstConnectionTimeout = window.setTimeout(this.setConnectionStatus, ConnectionStatusComponent.CHANGE_STATE_DELAY + 1e3);\n\n // let bool = true;\n // document.addEventListener('dblclick', () => {\n // this.setConnectionStatus(bool ? (bool = false, ConnectionStatus.Closed) : (bool = true, ConnectionStatus.Connected));\n // });\n }\n\n private setConnectionStatus = (overrideStatus?: ConnectionStatus) => {\n Promise.all([\n sessionStorage.get('dc'),\n rootScope.managers.rootScope.getConnectionStatus()\n ]).then(([baseDcId, connectionStatus]) => {\n if(!baseDcId) {\n baseDcId = App.baseDcId;\n }\n\n if(this.setFirstConnectionTimeout) {\n clearTimeout(this.setFirstConnectionTimeout);\n this.setFirstConnectionTimeout = 0;\n }\n\n const status = connectionStatus['NET-' + baseDcId];\n const online = status && (overrideStatus || status.status) === ConnectionStatus.Connected;\n\n if(this.connecting && online) {\n this.managers.apiUpdatesManager.forceGetDifference();\n }\n\n if(online && !this.hadConnect) {\n this.hadConnect = true;\n }\n\n this.timedOut = status && (overrideStatus || status.status) === ConnectionStatus.TimedOut;\n this.connecting = !online;\n this.retryAt = status && status.retryAt;\n DEBUG && this.log('connecting', this.connecting);\n this.setState();\n });\n };\n\n private setStatusText = (langPackKey: LangPackKey, args?: any[]) => {\n if(this.currentLangPackKey === langPackKey) return;\n this.currentLangPackKey = langPackKey;\n replaceContent(this.statusEl, i18n(langPackKey, args));\n this.statusPreloader.attach(this.statusEl);\n };\n\n private getA(langPackKey: LangPackKey, callback: () => void) {\n const a = document.createElement('a');\n a.classList.add('force-reconnect');\n a.append(i18n(langPackKey));\n attachClickEvent(a, (e) => {\n cancelEvent(e);\n callback();\n });\n\n return a;\n }\n\n private setState = () => {\n if(singleInstance.deactivatedReason) {\n return;\n }\n\n const timeout = ConnectionStatusComponent.CHANGE_STATE_DELAY;\n if(this.connecting) {\n if(this.timedOut) {\n const a = this.getA('ConnectionStatus.ForceReconnect', () => this.managers.networkerFactory.forceReconnect());\n this.setStatusText('ConnectionStatus.TimedOut', [a]);\n } else if(this.hadConnect) {\n if(this.retryAt !== undefined) {\n const timerSpan = document.createElement('span');\n const retryAt = this.retryAt;\n const setTime = () => {\n const now = Date.now();\n timerSpan.innerText = '' + Math.max(0, Math.round((retryAt - now) / 1000));\n if(now > retryAt) {\n clearInterval(interval);\n }\n };\n const interval = setInterval(setTime, 1e3);\n setTime();\n\n const a = this.getA('ConnectionStatus.Reconnect', () => this.managers.networkerFactory.forceReconnectTimeout());\n this.setStatusText('ConnectionStatus.ReconnectIn', [timerSpan, a]);\n } else {\n this.setStatusText('ConnectionStatus.Reconnecting');\n }\n } else {\n this.setStatusText('ConnectionStatus.Waiting');\n }\n } else if(this.updating) {\n this.setStatusText('Updating');\n }\n\n DEBUG && this.log('setState', this.connecting || this.updating);\n window.requestAnimationFrame(() => {\n if(this.setStateTimeout) clearTimeout(this.setStateTimeout);\n\n const cb = () => {\n SetTransition({\n element: this.statusContainer,\n className: 'is-shown',\n forwards: this.connecting || this.updating,\n duration: 200\n });\n this.setStateTimeout = 0;\n DEBUG && this.log('setState: isShown:', this.connecting || this.updating);\n };\n\n this.setStateTimeout = window.setTimeout(cb, timeout);\n // cb();\n /* if(timeout) this.setStateTimeout = window.setTimeout(cb, timeout);\n else cb(); */\n });\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {Message} from '../layer';\n/* import findUpClassName from \"../helpers/dom/findUpClassName\";\nimport rootScope from \"../lib/rootScope\";\nimport Transition from \"./transition\"; */\n\nexport enum SENDING_STATUS {\n Error = -1,\n Pending,\n Sent,\n Read\n}\n\nexport function getSendingStatus(message: Message.message | Message.messageService) {\n return message.pFlags.is_outgoing ?\n SENDING_STATUS.Pending : (\n message.pFlags.unread ?\n SENDING_STATUS.Sent :\n SENDING_STATUS.Read\n );\n}\n\ntype C = 'check' | 'checks' | 'sending' | 'sendingerror' | 'premium_lock';\nexport function setSendingStatus(\n container: HTMLElement,\n message?: C | Message.message | Message.messageService,\n disableAnimationIfRippleFound?: boolean\n) {\n let className: C;\n if(typeof(message) === 'string') {\n className = message;\n } else if(message?.pFlags.out) {\n if(message.error) {\n className = 'sendingerror';\n } else if(message.pFlags.is_outgoing) {\n className = 'sending';\n } else if(message.pFlags.unread) {\n className = 'check';\n } else {\n className = 'checks';\n }\n }\n\n if(!className) {\n container.textContent = '';\n return;\n }\n\n const iconClassName = 'tgico-' + className;\n const lastElement = container.lastElementChild as HTMLElement;\n if(lastElement && lastElement.classList.contains(iconClassName)) {\n return;\n }\n\n const element = document.createElement('i');\n element.classList.add('sending-status-icon', /* 'transition-item', */ iconClassName);\n container.append(element);\n\n if(lastElement) {\n lastElement.remove();\n }\n\n /* if(!lastElement) {\n element.classList.add('active');\n return;\n }\n\n const select = Transition(container, undefined, 350, () => {\n lastElement.remove();\n }, false, true, false);\n\n let animate = rootScope.settings.animationsEnabled && className !== 'sending' && !lastElement.classList.contains('tgico-sending');\n if(disableAnimationIfRippleFound && animate) {\n const parent = findUpClassName(container, 'rp');\n if(parent.querySelector('.c-ripple__circle') || parent.matches(':hover')) {\n animate = false;\n }\n }\n\n select(element, animate, lastElement); */\n\n /* SetTransition(lastElement, 'is-visible', false, 350, () => {\n // lastElement.remove();\n }, 2);\n SetTransition(element, 'is-visible', true, 350, undefined, 2); */\n}\n","// https://spicyyoghurt.com/tools/easing-functions\nexport default function easeInOutSine(t: number, b: number, c: number, d: number) {\n return t >= d ? b + c : easeInOutSineApply(t / d, c) + b;\n}\n\nexport function easeInOutSineApply(v: number, c: number) {\n return -c / 2 * (Math.cos(Math.PI * v) - 1);\n}\n","export default function roundRect(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number,\n radius: {[k in 'tl' | 'tr' | 'br' | 'bl']?: number} | number,\n fill?: boolean,\n stroke?: boolean\n) {\n const dpr = ctx.canvas.dpr;\n if(dpr) {\n x *= dpr;\n y *= dpr;\n width *= dpr;\n height *= dpr;\n }\n\n if(typeof(radius) === 'number') {\n if(dpr) radius *= dpr;\n radius = {tl: radius, tr: radius, br: radius, bl: radius};\n } else {\n const defaultRadius = {tl: 0, tr: 0, br: 0, bl: 0};\n for(const side in defaultRadius) {\n // @ts-ignore\n radius[side] = radius[side] ? (dpr ? radius[side] * dpr : radius[side]) : defaultRadius[side];\n }\n }\n\n ctx.beginPath();\n ctx.moveTo(x + radius.tl, y);\n ctx.lineTo(x + width - radius.tr, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + radius.tr);\n ctx.lineTo(x + width, y + height - radius.br);\n ctx.quadraticCurveTo(x + width, y + height, x + width - radius.br, y + height);\n ctx.lineTo(x + radius.bl, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - radius.bl);\n ctx.lineTo(x, y + radius.tl);\n ctx.quadraticCurveTo(x, y, x + radius.tl, y);\n ctx.closePath();\n\n if(fill) {\n ctx.fill();\n }\n\n if(stroke) {\n ctx.stroke();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {animate} from '../helpers/animation';\nimport customProperties from '../helpers/dom/customProperties';\nimport easeInOutSine from '../helpers/easing/easeInOutSine';\nimport mediaSizes from '../helpers/mediaSizes';\nimport roundRect from '../helpers/canvas/roundRect';\n\nconst DPR = window.devicePixelRatio;\nconst SIZE = 20 * DPR;\nconst MARGIN = 2.5 * DPR;\nconst WIDTH = 2 * DPR;\nconst RADIUS = 1 * DPR;\nconst LENGTH = 3;\n\nconst MIN_HEIGHT = 4;\nconst MAX_HEIGHT = 12;\nconst DURATION = 1000;\n\nexport default function groupCallActiveIcon(isActive = false) {\n const canvas = document.createElement('canvas');\n canvas.width = canvas.height = SIZE;\n const context = canvas.getContext('2d');\n\n const TOTAL_WIDTH = LENGTH * WIDTH + (LENGTH - 1) * MARGIN;\n const START_X = (SIZE - TOTAL_WIDTH) / 2;\n\n const startTime = Date.now();\n let wasMounted = false;\n // let hadRound = false;\n const renderFrame = () => {\n if(!canvas.isConnected) {\n if(wasMounted) {\n return false;\n }\n } else if(!wasMounted) {\n wasMounted = canvas.isConnected;\n }\n\n const time = Date.now();\n // if(((time - startTime) / DURATION) >= 1) {\n // hadRound = true;\n // }\n\n const progress = easeInOutSine((time - startTime) % DURATION, 0, 1, DURATION);\n\n context.clearRect(0, 0, SIZE, SIZE);\n context.fillStyle = isActive && !mediaSizes.isMobile ? customProperties.getProperty('primary-color') : '#fff';\n\n for(let i = 0; i < LENGTH; ++i) {\n const x = START_X + (i * WIDTH) + (i * MARGIN);\n\n let itemProgress: number;\n if(progress >= .5) {\n itemProgress = i % 2 ? 2 - progress * 2 : (progress - .5) * 2;\n } else {\n itemProgress = i % 2 ? progress * 2 : 1 - progress * 2;\n }\n\n let height = MIN_HEIGHT + (itemProgress * (MAX_HEIGHT - MIN_HEIGHT));\n /* if(!hadRound && i === 1) {\n console.log('call status animation', itemProgress, height, progress, progress >= .5);\n } */\n\n height *= DPR;\n const y = (SIZE - height) / 2;\n\n roundRect(context, x, y, WIDTH, height, RADIUS, true);\n }\n\n return true;\n };\n\n return {\n canvas,\n startAnimation: () => {\n animate(renderFrame);\n renderFrame();\n },\n setActive: (active: boolean) => {\n isActive = active;\n renderFrame();\n }\n };\n}\n","import customProperties from '../dom/customProperties';\nimport clamp from '../number/clamp';\n\nexport default class Shimmer {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private font = '30pt Helvetica';\n private currTime = Date.now();\n private diffTime = 0;\n private spread = 0;\n private paused = false;\n private pausedTime = 0;\n private pauseInterval = 850;\n private lightSource = 0;\n private inc = 0.032;\n private lightSpread = 0.55;\n private animations = ['slide', 'slide', 'slide', 'slide'];\n private currentAnimationIndex = 0;\n private text: string;\n private fillStyle: CanvasRenderingContext2D['fillStyle'];\n\n private keepTime() {\n this.diffTime = Date.now() - this.currTime;\n this.currTime = Date.now();\n }\n\n private cycleAnimation() {\n ++this.currentAnimationIndex;\n if(this.currentAnimationIndex >= this.animations.length) {\n this.currentAnimationIndex = 0;\n }\n }\n\n private animate() {\n const currentAnimation = this.animations[this.currentAnimationIndex];\n if(currentAnimation === 'glow') {\n return this.animateGlow(); // return glow style\n } else if(currentAnimation === 'slide') {\n return this.animateSlide(); // return slide gradient\n } else {\n console.log('unknown animation type: ' + String(currentAnimation));\n }\n }\n\n private animateGlow() {\n var glowEnd = 255,\n rgbStart = 68,\n r = rgbStart,\n g = r,\n b = r,\n increment = 10,\n interval = 800;\n\n return () => {\n var smartInc = increment * (this.diffTime / (1000 / 60));\n if(this.paused) {\n if((Date.now() - this.pausedTime) > interval) {\n r = rgbStart;\n this.cycleAnimation()\n this.paused = false;\n }\n } else {\n r = parseInt('' + (r + smartInc));\n if(r >= glowEnd) {\n this.paused = true;\n this.pausedTime = Date.now()\n }\n }\n return 'rgb('+ r + ',' + r + ',' + r + ')';\n };\n }\n\n private animateSlide(): CanvasGradient {\n var gradient = this.ctx.createLinearGradient(0, 0, this.canvas.width, 0),\n smartInc = this.inc * (this.diffTime / (1000 / 60)),\n lightLeft,\n lightRight,\n lightCenter;\n if(this.paused) {\n if((Date.now() - this.pausedTime) > this.pauseInterval) {\n this.lightSource = -0.6;\n this.cycleAnimation()\n this.paused = false;\n return this.animateSlide();\n }\n } else {\n this.lightSource += smartInc;\n if(this.lightSource > (1 + this.lightSpread)) {\n this.paused = true;\n this.pausedTime = Date.now();\n }\n }\n // lighting positions:\n lightCenter = clamp(this.lightSource, 0, 1);\n lightLeft = clamp(this.lightSource - this.lightSpread, 0, 1);\n lightRight = clamp(this.lightSource + this.lightSpread, 0, 1);\n\n const backgroundColor = customProperties.getProperty('background-color-true');\n const shimmerColor = customProperties.getProperty('surface-color');\n gradient.addColorStop(lightLeft, backgroundColor);\n gradient.addColorStop(lightCenter, shimmerColor);\n gradient.addColorStop(lightRight, backgroundColor);\n\n return gradient;\n }\n\n public settings(dict: Partial<{\n canvas: Shimmer['canvas'],\n fillStyle: Shimmer['fillStyle'],\n font: Shimmer['font'],\n lightSpread: Shimmer['lightSpread'],\n inc: Shimmer['inc'],\n animations: Shimmer['animations'],\n text: Shimmer['text']\n }> = {}) {\n this.canvas = dict.canvas ?? document.createElement('canvas');\n this.ctx = this.canvas.getContext('2d');\n this.font = dict.font ?? this.font;\n this.lightSpread = dict.lightSpread ?? this.lightSpread;\n this.inc = dict.inc ?? this.inc;\n this.animations = dict.animations ?? this.animations;\n this.text = dict.text ?? this.text;\n this.fillStyle = dict.fillStyle;\n\n this.canvas.classList.add('shimmer-canvas');\n }\n\n public on() {\n const {width, height} = this.canvas;\n // record the time we ran:\n this.keepTime();\n // clear and fill the canvas:\n this.ctx.clearRect(0, 0, width, height);\n\n if(this.font) {\n this.ctx.font = this.font;\n }\n\n this.ctx.fillStyle = this.animate() as any;\n this.ctx.fillRect(0, 0, width, height);\n\n if(this.fillStyle) {\n this.ctx.fillStyle = this.fillStyle;\n this.ctx.fillRect(0, 0, width, height);\n }\n\n if(this.text) {\n this.ctx.fillText(this.text, 50, 50);\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport Scrollable from '../components/scrollable';\nimport rootScope from '../lib/rootScope';\nimport {animate} from './animation';\nimport {drawCircleFromStart} from './canvas/drawCircle';\nimport roundRect from './canvas/roundRect';\nimport Shimmer from './canvas/shimmer';\nimport customProperties from './dom/customProperties';\nimport easeInOutSine from './easing/easeInOutSine';\nimport liteMode from './liteMode';\nimport mediaSizes from './mediaSizes';\n\nexport default class DialogsPlaceholder {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private shimmer: Shimmer;\n private tempId: number;\n private detachTime: number;\n\n private length: number;\n private dialogHeight: number;\n private availableLength: number;\n\n private avatarSize: number;\n private marginVertical: number;\n private totalHeight: number;\n private lineHeight: number;\n private lineBorderRadius: number;\n private lineMarginVertical: number;\n private statusWidth: number;\n private generatedValues: {\n firstLineWidth: number,\n secondLineWidth: number,\n statusWidth: number\n }[];\n\n private getRectFrom: () => DOMRectEditable;\n private onRemove: () => void;\n private blockScrollable: Scrollable;\n\n constructor(sizes: Partial<{\n avatarSize: number,\n marginVertical: number,\n totalHeight: number\n }> = {}) {\n this.shimmer = new Shimmer();\n this.tempId = 0;\n this.canvas = document.createElement('canvas');\n this.canvas.classList.add('dialogs-placeholder-canvas');\n this.ctx = this.canvas.getContext('2d');\n\n this.generatedValues = [];\n this.avatarSize = sizes.avatarSize ?? 54;\n this.marginVertical = sizes.marginVertical ?? 9;\n this.totalHeight = sizes.totalHeight ?? (this.avatarSize + this.marginVertical * 2);\n this.lineHeight = 10;\n this.lineBorderRadius = 6;\n this.lineMarginVertical = 8;\n this.statusWidth = 24;\n }\n\n public attach({container, rect, getRectFrom, onRemove, blockScrollable}: {\n container: HTMLElement,\n rect?: ReturnType<DialogsPlaceholder['getRectFrom']>,\n getRectFrom?: HTMLElement | DialogsPlaceholder['getRectFrom'],\n onRemove?: DialogsPlaceholder['onRemove'],\n blockScrollable?: DialogsPlaceholder['blockScrollable']\n }) {\n const {canvas} = this;\n\n this.onRemove = onRemove;\n this.getRectFrom = typeof(getRectFrom) === 'function' ? getRectFrom : (getRectFrom || container).getBoundingClientRect.bind(getRectFrom || container);\n if(this.blockScrollable = blockScrollable) {\n blockScrollable.container.style.overflowY = 'hidden';\n }\n\n this.updateCanvasSize(rect);\n this.startAnimation();\n container.append(canvas);\n }\n\n public detach(availableLength: number) {\n if(this.detachTime) {\n return;\n }\n\n this.availableLength = availableLength;\n this.detachTime = Date.now();\n\n if(!liteMode.isAvailable('animations')) {\n this.remove();\n }\n }\n\n public remove() {\n this.stopAnimation();\n\n if(this.canvas.parentElement) {\n this.canvas.remove();\n\n if(this.blockScrollable) {\n this.blockScrollable.container.style.overflowY = '';\n this.blockScrollable = undefined;\n }\n }\n\n this.onRemove?.();\n this.onRemove = undefined;\n }\n\n private updateCanvasSize(rect = this.getRectFrom()) {\n const {canvas} = this;\n const dpr = canvas.dpr = window.devicePixelRatio;\n canvas.width = rect.width * dpr;\n canvas.height = rect.height * dpr;\n canvas.style.width = rect.width + 'px';\n canvas.style.height = rect.height + 'px';\n }\n\n private renderDetachAnimationFrame() {\n const {\n canvas,\n ctx,\n detachTime,\n length,\n availableLength\n } = this;\n\n if(!detachTime) {\n return;\n } else if(!liteMode.isAvailable('animations')) {\n this.remove();\n return;\n }\n\n const {width} = canvas;\n\n ctx.globalCompositeOperation = 'destination-out';\n\n // ctx.fillStyle = 'rgba(0, 0, 0, 0)';\n // ctx.fillRect(0, 0, width, height);\n\n // const DURATION = 500;\n // const DELAY = DURATION;\n const DURATION = 150;\n const DELAY = 15;\n const elapsedTime = Date.now() - detachTime;\n let completed = true;\n for(let i = 0; i < length; ++i) {\n const delay = availableLength < length && i >= availableLength ? DELAY * (availableLength - 1) : DELAY * i;\n const elapsedRowTime = elapsedTime - delay;\n if(elapsedRowTime <= 0) {\n completed = false;\n continue;\n }\n\n const progress = easeInOutSine(elapsedRowTime, 0, 1, DURATION);\n\n ctx.beginPath();\n ctx.rect(0, this.dialogHeight * i, width, this.dialogHeight);\n ctx.fillStyle = `rgba(0, 0, 0, ${progress})`;\n ctx.fill();\n\n if(progress < 1) {\n completed = false;\n }\n }\n\n // const totalRadius = Math.sqrt(width ** 2 + height ** 2);\n // const gradient = ctx.createRadialGradient(\n // 0, 0, 0,\n // 0, 0, totalRadius);\n // gradient.addColorStop(0, 'rgba(0, 0, 0, 1)');\n // gradient.addColorStop(progress, 'rgba(0, 0, 0, 0)');\n // gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');\n\n // const gradient = ctx.createLinearGradient(0, 0, 0, height);\n // gradient.addColorStop(0, 'rgba(0, 0, 0, 1)');\n // gradient.addColorStop(progress, 'rgba(0, 0, 0, 0)');\n // gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');\n\n // ctx.fillStyle = gradient;\n // ctx.fillRect(0, 0, width, height);\n\n ctx.globalCompositeOperation = 'source-over';\n\n if(completed) {\n this.remove();\n }\n }\n\n private renderFrame() {\n this.shimmer.on();\n this.renderDetachAnimationFrame();\n }\n\n private startAnimation() {\n const {canvas, shimmer} = this;\n const tempId = ++this.tempId;\n const pattern = this.createPattern();\n\n shimmer.settings({\n canvas,\n fillStyle: pattern\n });\n\n const middleware = () => {\n return this.tempId === tempId;\n };\n\n this.renderFrame();\n animate(() => {\n if(!middleware()) {\n return false;\n }\n\n // ! should've removed the loop if animations are disabled\n if(liteMode.isAvailable('animations')) {\n this.renderFrame();\n }\n\n // ! tempId can be changed during renderFrame\n return middleware();\n });\n\n rootScope.addEventListener('theme_change', this.onThemeChange);\n mediaSizes.addEventListener('resize', this.onResize);\n }\n\n private stopAnimation() {\n ++this.tempId;\n rootScope.removeEventListener('theme_change', this.onThemeChange);\n mediaSizes.removeEventListener('resize', this.onResize);\n }\n\n private onThemeChange = () => {\n this.stopAnimation();\n this.startAnimation();\n };\n\n private onResize = () => {\n const {canvas} = this;\n const {width, height, dpr} = canvas;\n this.updateCanvasSize();\n if(canvas.width === width && canvas.height === height && canvas.dpr === dpr) {\n return;\n }\n\n this.stopAnimation();\n this.startAnimation();\n };\n\n private createPattern() {\n const {canvas, ctx} = this;\n\n const patternCanvas = document.createElement('canvas');\n const patternContext = patternCanvas.getContext('2d');\n const dpr = canvas.dpr;\n patternCanvas.dpr = dpr;\n patternCanvas.width = canvas.width;\n patternCanvas.height = canvas.height;\n\n patternContext.fillStyle = customProperties.getProperty('surface-color');\n patternContext.fillRect(0, 0, patternCanvas.width, patternCanvas.height);\n\n patternContext.fillStyle = '#000';\n patternContext.globalCompositeOperation = 'destination-out';\n\n const dialogHeight = this.dialogHeight = this.totalHeight * dpr;\n const length = this.length = Math.ceil(canvas.height / dialogHeight);\n for(let i = 0; i < length; ++i) {\n this.drawChat(patternContext, i, i * dialogHeight);\n }\n\n return ctx.createPattern(patternCanvas, 'no-repeat');\n }\n\n private drawChat(ctx: CanvasRenderingContext2D, i: number, y: number) {\n let generatedValues = this.generatedValues[i];\n if(!generatedValues) {\n generatedValues = this.generatedValues[i] = {\n firstLineWidth: 40 + Math.random() * 100, // 120\n secondLineWidth: 120 + Math.random() * 130, // 240\n statusWidth: 24 + Math.random() * 16\n };\n }\n\n const {\n firstLineWidth,\n secondLineWidth,\n statusWidth\n } = generatedValues;\n\n const {canvas} = ctx;\n const {dpr} = canvas;\n y /= dpr;\n\n const {\n avatarSize,\n marginVertical,\n lineHeight,\n lineBorderRadius,\n lineMarginVertical\n } = this;\n\n let marginLeft = 17;\n\n if(avatarSize) {\n drawCircleFromStart(ctx, marginLeft, y + marginVertical, avatarSize / 2, true);\n marginLeft += avatarSize + 10;\n }\n\n // 9 + 54 - 10 - 8 = 45 ........ 72 - 9 - 10 - 8\n roundRect(ctx, marginLeft, y + marginVertical + lineMarginVertical, firstLineWidth, lineHeight, lineBorderRadius, true);\n // roundRect(ctx, marginLeft, y + marginVertical + avatarSize - lineHeight - lineMarginVertical, secondLineWidth, lineHeight, lineBorderRadius, true);\n roundRect(ctx, marginLeft, y + this.totalHeight - marginVertical - lineHeight - lineMarginVertical, secondLineWidth, lineHeight, lineBorderRadius, true);\n\n roundRect(ctx, canvas.width / dpr - 24 - statusWidth, y + marginVertical + lineMarginVertical, statusWidth, lineHeight, lineBorderRadius, true);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDialogFilter as DialogFilter, MyDialogFilter} from '../storages/filters';\nimport type LazyLoadQueue from '../../components/lazyLoadQueue';\nimport type {Dialog, ForumTopic, MyMessage} from './appMessagesManager';\nimport type {MyPhoto} from './appPhotosManager';\nimport type {MyDocument} from './appDocsManager';\nimport type {State} from '../../config/state';\nimport AvatarElement from '../../components/avatar';\nimport DialogsContextMenu from '../../components/dialogsContextMenu';\nimport {horizontalMenu} from '../../components/horizontalMenu';\nimport ripple from '../../components/ripple';\nimport Scrollable, {ScrollableX, SliceSides} from '../../components/scrollable';\nimport {formatDateAccordingToTodayNew} from '../../helpers/date';\nimport {IS_MOBILE_SAFARI, IS_SAFARI} from '../../environment/userAgent';\nimport {logger, LogTypes} from '../logger';\nimport rootScope from '../rootScope';\nimport appImManager, {AppImManager, APP_TABS} from './appImManager';\nimport Button from '../../components/button';\nimport SetTransition from '../../components/singleTransition';\nimport {MyDraftMessage} from './appDraftsManager';\nimport DEBUG, {MOUNT_CLASS_TO} from '../../config/debug';\nimport PeerTitle from '../../components/peerTitle';\nimport I18n, {FormatterArguments, i18n, LangPackKey, _i18n} from '../langPack';\nimport findUpTag from '../../helpers/dom/findUpTag';\nimport lottieLoader from '../rlottie/lottieLoader';\nimport wrapPhoto from '../../components/wrappers/photo';\nimport AppEditFolderTab from '../../components/sidebarLeft/tabs/editFolder';\nimport appSidebarLeft from '../../components/sidebarLeft';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport positionElementByIndex from '../../helpers/dom/positionElementByIndex';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport ConnectionStatusComponent from '../../components/connectionStatus';\nimport {renderImageFromUrlPromise} from '../../helpers/dom/renderImageFromUrl';\nimport {fastRafConventional, fastRafPromise} from '../../helpers/schedulers';\nimport SortedUserList from '../../components/sortedUserList';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport handleTabSwipe from '../../helpers/dom/handleTabSwipe';\nimport windowSize from '../../helpers/windowSize';\nimport isInDOM from '../../helpers/dom/isInDOM';\nimport {setSendingStatus} from '../../components/sendingStatus';\nimport SortedList, {SortedElementBase} from '../../helpers/sortedList';\nimport debounce from '../../helpers/schedulers/debounce';\nimport {FOLDER_ID_ALL, FOLDER_ID_ARCHIVE, NULL_PEER_ID, REAL_FOLDERS, REAL_FOLDER_ID} from '../mtproto/mtproto_config';\nimport groupCallActiveIcon from '../../components/groupCallActiveIcon';\nimport {Chat, Message, NotifyPeer} from '../../layer';\nimport IS_GROUP_CALL_SUPPORTED from '../../environment/groupCallSupport';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport appNavigationController, {NavigationItem} from '../../components/appNavigationController';\nimport appMediaPlaybackController from '../../components/appMediaPlaybackController';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport {AppManagers} from './managers';\nimport appSidebarRight from '../../components/sidebarRight';\nimport PopupElement from '../../components/popups';\nimport choosePhotoSize from './utils/photos/choosePhotoSize';\nimport wrapEmojiText from '../richTextProcessor/wrapEmojiText';\nimport wrapMessageForReply from '../../components/wrappers/messageForReply';\nimport isMessageRestricted from './utils/messages/isMessageRestricted';\nimport getMediaFromMessage from './utils/messages/getMediaFromMessage';\nimport getMessageSenderPeerIdOrName from './utils/messages/getMessageSenderPeerIdOrName';\nimport wrapStickerEmoji from '../../components/wrappers/stickerEmoji';\nimport getDialogIndexKey from './utils/dialogs/getDialogIndexKey';\nimport getProxiedManagers from './getProxiedManagers';\nimport getDialogIndex from './utils/dialogs/getDialogIndex';\nimport {attachContextMenuListener} from '../../helpers/dom/attachContextMenuListener';\nimport deferredPromise, {CancellablePromise} from '../../helpers/cancellablePromise';\nimport wrapPeerTitle from '../../components/wrappers/peerTitle';\nimport middlewarePromise from '../../helpers/middlewarePromise';\nimport appDownloadManager from './appDownloadManager';\nimport groupCallsController from '../calls/groupCallsController';\nimport callsController from '../calls/callsController';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport noop from '../../helpers/noop';\nimport DialogsPlaceholder from '../../helpers/dialogsPlaceholder';\nimport pause from '../../helpers/schedulers/pause';\nimport apiManagerProxy from '../mtproto/mtprotoworker';\nimport filterAsync from '../../helpers/array/filterAsync';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport whichChild from '../../helpers/dom/whichChild';\nimport {getMiddleware, MiddlewareHelper} from '../../helpers/middleware';\nimport makeError from '../../helpers/makeError';\nimport getUnsafeRandomInt from '../../helpers/number/getUnsafeRandomInt';\nimport Row, {RowMediaSizeType} from '../../components/row'\nimport SettingSection from '../../components/settingSection';\nimport {SliderSuperTabEventable} from '../../components/sliderTab';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport {AckedResult} from '../mtproto/superMessagePort';\nimport ButtonMenuToggle from '../../components/buttonMenuToggle';\nimport getMessageThreadId from './utils/messages/getMessageThreadId';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport formatNumber from '../../helpers/number/formatNumber';\nimport AppSharedMediaTab from '../../components/sidebarRight/tabs/sharedMedia';\nimport {dispatchHeavyAnimationEvent} from '../../hooks/useHeavyAnimationCheck';\nimport AppArchivedTab from '../../components/sidebarLeft/tabs/archivedTab';\nimport shake from '../../helpers/dom/shake';\nimport AppEditTopicTab from '../../components/sidebarRight/tabs/editTopic';\nimport getServerMessageId from './utils/messageId/getServerMessageId';\n\nexport const DIALOG_LIST_ELEMENT_TAG = 'A';\n\nexport type DialogDom = {\n avatarEl: AvatarElement,\n captionDiv: HTMLElement,\n titleSpan: HTMLSpanElement,\n titleSpanContainer: HTMLSpanElement,\n statusSpan: HTMLSpanElement,\n lastTimeSpan: HTMLSpanElement,\n unreadBadge?: HTMLElement,\n unreadAvatarBadge?: HTMLElement,\n callIcon?: ReturnType<typeof groupCallActiveIcon>,\n mentionsBadge?: HTMLElement,\n lastMessageSpan: HTMLSpanElement,\n containerEl: HTMLElement,\n listEl: HTMLElement,\n subtitleEl: HTMLElement,\n\n setLastMessagePromise?: CancellablePromise<void>,\n setUnreadMessagePromise?: CancellablePromise<void>\n};\n\ninterface SortedDialog extends SortedElementBase<PeerId> {\n dom: DialogDom,\n dialogElement: DialogElement\n}\n\nfunction setPromiseMiddleware<T extends {[smth in K as K]?: CancellablePromise<void>}, K extends keyof T>(obj: T, key: K) {\n const oldPromise: CancellablePromise<void> = obj[key] as any;\n oldPromise?.reject();\n\n // @ts-ignore\n const deferred = obj[key] = deferredPromise<void>();\n deferred.catch(() => {}).finally(() => {\n if((obj[key] as any) === deferred) {\n delete obj[key];\n }\n });\n\n const middleware = middlewarePromise(() => (obj[key] as any) === deferred);\n return {deferred, middleware};\n}\n\nconst BADGE_SIZE = 22;\nconst BADGE_TRANSITION_TIME = 250;\n\nclass SortedDialogList extends SortedList<SortedDialog> {\n public managers: AppManagers;\n public log: ReturnType<typeof logger>;\n public list: HTMLElement;\n public indexKey: ReturnType<typeof getDialogIndexKey>;\n public onListLengthChange: () => void;\n public forumPeerId: PeerId;\n\n constructor(options: {\n managers: SortedDialogList['managers'],\n log?: SortedDialogList['log'],\n list: SortedDialogList['list'],\n indexKey: SortedDialogList['indexKey'],\n onListLengthChange?: SortedDialogList['onListLengthChange'],\n forumPeerId?: SortedDialogList['forumPeerId']\n }) {\n super({\n getIndex: (element) => this.managers.dialogsStorage.getDialogIndex(this.forumPeerId ?? element.id, this.indexKey, this.forumPeerId ? element.id : undefined),\n onDelete: (element) => {\n element.dom.listEl.remove();\n this.onListLengthChange?.();\n },\n onSort: (element, idx) => {\n const willChangeLength = element.dom.listEl.parentElement !== this.list;\n positionElementByIndex(element.dom.listEl, this.list, idx);\n\n if(willChangeLength) {\n this.onListLengthChange?.();\n }\n },\n onElementCreate: async(base) => {\n const loadPromises: Promise<any>[] = [];\n\n const dialogElement = appDialogsManager.addListDialog({\n peerId: this.forumPeerId ?? base.id,\n loadPromises,\n isBatch: true,\n threadId: this.forumPeerId ? base.id : undefined,\n isMainList: this.indexKey === 'index_0'\n });\n (base as SortedDialog).dom = dialogElement.dom;\n (base as SortedDialog).dialogElement = dialogElement;\n\n await Promise.all(loadPromises);\n return base as SortedDialog;\n },\n updateElementWith: fastRafConventional,\n log: options.log\n });\n\n safeAssign(this, options);\n }\n\n public clear() {\n this.list.replaceChildren();\n super.clear();\n }\n}\n\nexport type DialogElementSize = RowMediaSizeType;\ntype DialogElementOptions = {\n peerId: PeerId,\n rippleEnabled?: boolean,\n onlyFirstName?: boolean,\n meAsSaved?: boolean,\n avatarSize?: RowMediaSizeType,\n autonomous?: boolean,\n loadPromises?: Promise<any>[],\n fromName?: string,\n noIcons?: boolean,\n threadId?: number,\n wrapOptions?: WrapSomethingOptions,\n isMainList?: boolean\n};\nexport class DialogElement extends Row {\n public dom: DialogDom;\n\n constructor({\n peerId,\n rippleEnabled = true,\n onlyFirstName = false,\n meAsSaved = true,\n avatarSize = 'bigger',\n autonomous,\n loadPromises,\n fromName,\n noIcons,\n threadId,\n wrapOptions = {},\n isMainList\n }: DialogElementOptions) {\n super({\n clickable: true,\n noRipple: !rippleEnabled,\n havePadding: !threadId,\n title: true,\n titleRightSecondary: true,\n subtitle: true,\n subtitleRight: true,\n noWrap: true,\n asLink: true\n });\n\n this.subtitleRight.remove();\n\n const avatarEl = threadId ? undefined : new AvatarElement();\n if(avatarEl) {\n const avatarSizeMap: {[k in DialogElementSize]?: number} = {\n bigger: 54,\n abitbigger: 42,\n small: 32\n };\n const s = avatarSizeMap[avatarSize];\n avatarEl.classList.add('dialog-avatar', 'avatar-' + s);\n avatarEl.updateWithOptions({\n loadPromises,\n lazyLoadQueue: wrapOptions.lazyLoadQueue,\n isDialog: !!meAsSaved,\n peerId,\n peerTitle: fromName\n });\n\n this.applyMediaElement(avatarEl, avatarSize);\n }\n\n const captionDiv = this.container;\n\n const titleSpanContainer = this.title;\n titleSpanContainer.classList.add('user-title');\n\n this.titleRow.classList.add('dialog-title');\n\n const peerTitle = new PeerTitle();\n const peerTitlePromise = peerTitle.update({\n peerId,\n fromName,\n dialog: meAsSaved,\n onlyFirstName,\n withIcons: !noIcons,\n threadId: threadId\n });\n\n loadPromises?.push(peerTitlePromise);\n titleSpanContainer.append(peerTitle.element);\n\n // for muted icon\n titleSpanContainer.classList.add('tgico'); // * эта строка будет актуальна только для !container, но ладно\n\n // const titleIconsPromise = generateTitleIcons(peerId).then((elements) => {\n // titleSpanContainer.append(...elements);\n // });\n\n // if(loadPromises) {\n // loadPromises.push(titleIconsPromise);\n // }\n // }\n\n const span = this.subtitle;\n // span.classList.add('user-last-message');\n\n const li = this.container;\n li.classList.add('chatlist-chat', 'chatlist-chat-' + avatarSize);\n if(!autonomous) {\n (li as HTMLAnchorElement).href = '#' + peerId;\n }\n // if(rippleEnabled) {\n // ripple(li);\n // }\n\n if(avatarSize === 'bigger') {\n this.container.classList.add('row-big');\n } else if(avatarSize === 'small') {\n this.container.classList.add('row-small');\n }\n\n li.dataset.peerId = '' + peerId;\n if(threadId) {\n li.dataset.threadId = '' + threadId;\n }\n\n const statusSpan = document.createElement('span');\n statusSpan.classList.add('message-status', 'sending-status'/* , 'transition', 'reveal' */);\n\n const lastTimeSpan = document.createElement('span');\n lastTimeSpan.classList.add('message-time');\n\n const rightSpan = this.titleRight;\n rightSpan.classList.add('dialog-title-details');\n rightSpan.append(statusSpan, lastTimeSpan);\n\n this.subtitleRow.classList.add('dialog-subtitle');\n\n const dom: DialogDom = this.dom = {\n avatarEl,\n captionDiv,\n titleSpan: peerTitle.element,\n titleSpanContainer,\n statusSpan,\n lastTimeSpan,\n lastMessageSpan: span,\n containerEl: li,\n listEl: li,\n subtitleEl: this.subtitleRow\n };\n\n if(!autonomous) {\n (li as any).dialogDom = dom;\n\n const chat = appImManager.chat;\n if(chat && appImManager.isSamePeer(chat, {peerId, threadId: threadId, type: 'chat'})) {\n appDialogsManager.setDialogActive(li, true);\n }\n\n if(isMainList && appDialogsManager.forumTab?.peerId === peerId && !threadId) {\n li.classList.add('is-forum-open');\n }\n }\n }\n\n public createUnreadBadge() {\n if(this.dom.unreadBadge) return;\n const badge = this.dom.unreadBadge = document.createElement('div');\n badge.className = `dialog-subtitle-badge badge badge-${BADGE_SIZE}`;\n this.dom.subtitleEl.append(badge);\n }\n\n public createUnreadAvatarBadge() {\n if(this.dom.unreadAvatarBadge) return;\n const badge = this.dom.unreadAvatarBadge = document.createElement('div');\n badge.className = `dialog-subtitle-badge badge badge-${BADGE_SIZE} avatar-badge`;\n this.dom.listEl.append(badge);\n }\n\n public createMentionsBadge() {\n if(this.dom.mentionsBadge) return;\n const badge = this.dom.mentionsBadge = document.createElement('div');\n badge.className = `dialog-subtitle-badge badge badge-${BADGE_SIZE} mention mention-badge`;\n badge.innerText = '@';\n this.dom.lastMessageSpan.after(badge);\n }\n\n public toggleBadgeByKey(\n key: Extract<keyof DialogDom, 'unreadBadge' | 'unreadAvatarBadge' | 'mentionsBadge'>,\n hasBadge: boolean,\n justCreated: boolean,\n batch?: boolean\n ) {\n SetTransition({\n element: this.dom[key],\n className: 'is-visible',\n forwards: hasBadge,\n duration: batch ? 0 : BADGE_TRANSITION_TIME,\n onTransitionEnd: hasBadge ? undefined : () => {\n this.dom[key].remove();\n delete this.dom[key];\n },\n useRafs: !justCreated || !isInDOM(this.dom[key]) ? 2 : 0\n });\n }\n}\n\nclass ForumTab extends SliderSuperTabEventable {\n private rows: HTMLElement;\n private subtitle: HTMLElement;\n\n public peerId: PeerId;\n private firstTime: boolean;\n\n private log: ReturnType<typeof logger>;\n\n private xd: Some3;\n\n public async toggle(value: boolean) {\n if(this.init2) {\n await this.init2();\n }\n\n SetTransition({\n element: this.container,\n className: 'is-visible',\n forwards: value,\n duration: 300,\n onTransitionEnd: !value ? () => {\n this.onCloseAfterTimeout();\n } : undefined,\n useRafs: this.firstTime ? (this.firstTime = undefined, 2) : undefined\n });\n }\n\n public init(options: {\n peerId: PeerId,\n managers: AppManagers\n }) {\n safeAssign(this, options);\n\n this.log = logger('FORUM');\n this.firstTime = true;\n this.container.classList.add('topics-container');\n\n const isFloating = !this.slider;\n if(isFloating) {\n this.closeBtn.classList.replace('tgico-left', 'tgico-close');\n this.container.classList.add('active', 'is-floating');\n\n attachClickEvent(this.closeBtn, () => {\n appDialogsManager.toggleForumTab(undefined, this);\n }, {listenerSetter: this.listenerSetter});\n }\n\n this.rows = document.createElement('div');\n this.rows.classList.add('sidebar-header__rows');\n\n this.subtitle = document.createElement('div');\n this.subtitle.classList.add('sidebar-header__subtitle');\n\n this.title.replaceWith(this.rows);\n this.rows.append(this.title, this.subtitle);\n\n const list = appDialogsManager.createChatList();\n appDialogsManager.setListClickListener(list, null, true);\n this.scrollable.append(list);\n\n this.xd = new Some3(this.peerId, isFloating ? 80 : 0);\n this.xd.scrollable = this.scrollable;\n this.xd.sortedList = new SortedDialogList({\n managers: this.managers,\n log: this.log,\n list,\n indexKey: 'index_0',\n forumPeerId: this.peerId\n });\n this.xd.bindScrollable();\n\n const getOptionsForMessages = (): Parameters<AppImManager['isSamePeer']>[0] => {\n return {\n peerId: this.peerId,\n type: 'chat'\n };\n };\n\n const btnMenu = ButtonMenuToggle({\n listenerSetter: this.listenerSetter,\n direction: 'bottom-left',\n buttons: [{\n icon: 'info',\n text: 'ForumTopic.Context.Info',\n onClick: async() => {\n const tab = appSidebarLeft.createTab(AppSharedMediaTab, true);\n tab.isFirst = true;\n tab.setPeer(this.peerId);\n (await tab.fillProfileElements())();\n tab.loadSidebarMedia(true);\n tab.open();\n }\n }, {\n icon: 'message',\n text: 'ForumTopic.Context.ShowAsMessages',\n onClick: () => {\n const chat = appImManager.chat;\n appImManager[chat?.peerId === this.peerId ? 'setPeer' : 'setInnerPeer'](getOptionsForMessages());\n },\n verify: () => {\n const chat = appImManager.chat;\n return !chat || !appImManager.isSamePeer(chat, getOptionsForMessages());\n }\n }, {\n icon: 'adduser',\n text: 'ForumTopic.Context.AddMember',\n onClick: () => {},\n verify: () => false && this.managers.appChatsManager.hasRights(this.peerId.toChatId(), 'invite_users')\n }, {\n icon: 'add',\n text: 'ForumTopic.Context.New',\n onClick: () => {\n appSidebarLeft.createTab(AppEditTopicTab).open(this.peerId);\n },\n separator: true,\n verify: () => this.managers.appChatsManager.hasRights(this.peerId.toChatId(), 'manage_topics')\n }]\n });\n\n this.listenerSetter.add(rootScope)('history_reload', (peerId) => {\n if(this.peerId !== peerId) {\n return;\n }\n\n this.xd.fullReset();\n });\n\n this.listenerSetter.add(rootScope)('chat_update', async(chatId) => {\n if(this.peerId !== chatId.toPeerId(true)) {\n return;\n }\n\n const chat = await this.managers.appChatsManager.getChat(chatId);\n if(!(chat as Chat.channel).pFlags.forum) {\n appDialogsManager.toggleForumTab(undefined, this);\n }\n });\n\n if(IS_TOUCH_SUPPORTED) {\n handleTabSwipe({\n element: this.container,\n onSwipe: () => {\n appDialogsManager.toggleForumTab(undefined, this);\n },\n middleware: this.middlewareHelper.get()\n });\n }\n\n this.header.append(btnMenu);\n\n if(!isFloating) {\n return this.init2();\n }\n }\n\n public async init2() {\n this.init2 = undefined;\n\n const middleware = this.middlewareHelper.get();\n const peerId = this.peerId;\n\n this.managers.apiUpdatesManager.subscribeToChannelUpdates(this.peerId.toChatId());\n middleware.onDestroy(() => {\n this.managers.apiUpdatesManager.unsubscribeFromChannelUpdates(this.peerId.toChatId());\n });\n\n const peerTitlePromise = wrapPeerTitle({\n peerId,\n dialog: true,\n wrapOptions: {middleware}\n });\n\n const setStatusPromise = appImManager.setPeerStatus({\n peerId,\n element: this.subtitle,\n needClear: true,\n useWhitespace: false,\n middleware,\n noTyping: true\n });\n\n // this.managers.dialogsStorage.getForumTopics(this.peerId).then((messagesForumTopics) => {\n // console.log(messagesForumTopics);\n\n // const promises = messagesForumTopics.topics.map((forumTopic) => {\n // return this.sortedDialogList.add(forumTopic.id);\n // });\n\n // return Promise.all(promises);\n // }).then(() => {\n // this.dialogsPlaceholder.detach(this.sortedDialogList.getAll().size);\n // });\n\n return Promise.all([\n peerTitlePromise,\n setStatusPromise,\n this.xd.onChatsScroll().then((loadResult) => {\n return loadResult.cached ? loadResult.renderPromise : undefined\n })\n ]).then(([\n peerTitle,\n setStatus,\n _\n ]) => {\n if(!middleware()) {\n return;\n }\n\n this.title.append(peerTitle);\n setStatus?.();\n });\n }\n\n public onCloseAfterTimeout() {\n super.onCloseAfterTimeout();\n this.xd.destroy();\n }\n}\n\nconst NOT_IMPLEMENTED_ERROR = new Error('not implemented');\n\ntype DialogKey = Parameters<Some['sortedList']['delete']>[0];\nclass Some<T extends Dialog | ForumTopic = Dialog | ForumTopic> {\n public sortedList: SortedDialogList;\n public scrollable: Scrollable;\n public loadedDialogsAtLeastOnce: boolean;\n public needPlaceholderAtFirstTime: boolean;\n protected offsets: {top: number, bottom: number};\n protected indexKey: ReturnType<typeof getDialogIndexKey>;\n protected sliceTimeout: number;\n protected managers: AppManagers;\n protected listenerSetter: ListenerSetter;\n protected loadDialogsPromise: Promise<{cached: boolean, renderPromise: Some2['loadDialogsRenderPromise']}>;\n protected loadDialogsRenderPromise: Promise<void>;\n protected placeholder: DialogsPlaceholder;\n protected log: ReturnType<typeof logger>;\n protected placeholderOptions: ConstructorParameters<typeof DialogsPlaceholder>[0];\n\n constructor() {\n this.log = logger('CL');\n this.offsets = {top: 0, bottom: 0};\n this.managers = rootScope.managers;\n this.listenerSetter = new ListenerSetter();\n }\n\n public getOffsetIndex(side: 'top' | 'bottom') {\n return {index: this.scrollable.loadedAll[side] ? 0 : this.offsets[side]};\n }\n\n protected isDialogMustBeInViewport(dialog: T) {\n // return true;\n const topOffset = this.getOffsetIndex('top');\n const bottomOffset = this.getOffsetIndex('bottom');\n\n if(!topOffset.index && !bottomOffset.index) {\n return true;\n }\n\n const index = getDialogIndex(dialog, this.indexKey);\n return (!topOffset.index || index <= topOffset.index) &&\n (!bottomOffset.index || index >= bottomOffset.index);\n }\n\n public setIndexKey(indexKey: Some['indexKey']) {\n this.indexKey = indexKey;\n this.sortedList.indexKey = indexKey;\n }\n\n protected deleteDialogByKey(key: DialogKey) {\n this.sortedList.delete(key);\n }\n\n public deleteDialog(dialog: T) {\n return this.deleteDialogByKey(this.getDialogKey(dialog));\n }\n\n public updateDialog(dialog: T) {\n const key = this.getDialogKey(dialog);\n if(this.isDialogMustBeInViewport(dialog)) {\n if(!this.sortedList.has(key) && this.loadedDialogsAtLeastOnce) {\n this.sortedList.add(key);\n return;\n }\n } else {\n this.deleteDialog(dialog);\n return;\n }\n\n const dialogElement = this.getDialogElement(key);\n if(dialogElement) {\n appDialogsManager.setLastMessageN({\n dialog,\n dialogElement,\n setUnread: true\n });\n this.sortedList.update(key);\n }\n }\n\n public onChatsRegularScroll = () => {\n // return;\n\n if(this.sliceTimeout) clearTimeout(this.sliceTimeout);\n this.sliceTimeout = window.setTimeout(() => {\n this.sliceTimeout = undefined;\n\n if(!this.sortedList.list.childElementCount || appDialogsManager.processContact) {\n return;\n }\n\n /* const observer = new IntersectionObserver((entries) => {\n const\n });\n\n Array.from(this.chatList.children).forEach((el) => {\n observer.observe(el);\n }); */\n\n fastRafConventional(() => {\n const perf = performance.now();\n\n const scrollTopWas = this.scrollable.scrollTop;\n\n const firstElementChild = this.sortedList.list.firstElementChild;\n const rectContainer = this.scrollable.container.getBoundingClientRect();\n const rectTarget = firstElementChild.getBoundingClientRect();\n const children = Array.from(this.scrollable.splitUp.children) as HTMLElement[];\n\n // const padding = 8;\n // const offsetTop = this.folders.container.offsetTop;\n let offsetTop = this.scrollable.splitUp.offsetTop;\n if(offsetTop && scrollTopWas < offsetTop) offsetTop -= scrollTopWas;\n // const offsetTop = scrollTopWas < padding ? padding - scrollTopWas : 0;\n const firstY = rectContainer.y + offsetTop;\n const lastY = rectContainer.y/* - 8 */; // 8px - .chatlist padding-bottom\n\n const firstElement = findUpTag(document.elementFromPoint(Math.ceil(rectTarget.x), Math.ceil(firstY + 1)), firstElementChild.tagName) as HTMLElement;\n const lastElement = findUpTag(document.elementFromPoint(Math.ceil(rectTarget.x), Math.floor(lastY + rectContainer.height - 1)), firstElementChild.tagName) as HTMLElement;\n\n // alert('got element:' + rect.y);\n\n if(!firstElement || !lastElement) {\n return;\n }\n\n // alert('got element:' + !!firstElement);\n\n const firstElementRect = firstElement.getBoundingClientRect();\n const elementOverflow = firstElementRect.y - firstY;\n\n const sliced: HTMLElement[] = [];\n const firstIndex = children.indexOf(firstElement);\n const lastIndex = children.indexOf(lastElement);\n\n const saveLength = 10;\n\n const sliceFromStart = IS_SAFARI ? [] : children.slice(0, Math.max(0, firstIndex - saveLength));\n const sliceFromEnd = children.slice(lastIndex + saveLength);\n\n /* if(sliceFromStart.length !== sliceFromEnd.length) {\n console.log('not equal', sliceFromStart.length, sliceFromEnd.length);\n }\n\n if(sliceFromStart.length > sliceFromEnd.length) {\n const diff = sliceFromStart.length - sliceFromEnd.length;\n sliceFromStart.splice(0, diff);\n } else if(sliceFromEnd.length > sliceFromStart.length) {\n const diff = sliceFromEnd.length - sliceFromStart.length;\n sliceFromEnd.splice(sliceFromEnd.length - diff, diff);\n } */\n\n if(sliceFromStart.length) {\n this.scrollable.loadedAll.top = false;\n }\n\n if(sliceFromEnd.length) {\n this.scrollable.loadedAll.bottom = false;\n }\n\n sliced.push(...sliceFromStart);\n sliced.push(...sliceFromEnd);\n\n sliced.forEach((el) => {\n this.deleteDialogByKey(this.getDialogKeyFromElement(el));\n });\n\n this.setOffsets();\n\n // this.log('[slicer] elements', firstElement, lastElement, rect, sliced, sliceFromStart.length, sliceFromEnd.length);\n\n // this.log('[slicer] reset scrollTop', this.scroll.scrollTop, firstElement.offsetTop, firstElementRect.y, rect.y, elementOverflow);\n\n // alert('left length:' + children.length);\n\n const scrollTop = firstElement.offsetTop - elementOverflow;\n this.scrollable.scrollTop = this.scrollable.lastScrollPosition = scrollTop;\n\n this.log('slice time', performance.now() - perf, this.indexKey, scrollTop);\n /* const firstElementRect = firstElement.getBoundingClientRect();\n const scrollTop = */\n\n // this.scroll.scrollIntoView(firstElement, false);\n });\n }, 200);\n };\n\n public onChatsScrollTop() {\n return this.onChatsScroll('top');\n };\n\n public onChatsScroll(side: SliceSides = 'bottom') {\n return this.loadDialogs(side);\n };\n\n public createPlaceholder(): DialogsPlaceholder {\n const placeholder = this.placeholder = new DialogsPlaceholder(this.placeholderOptions);\n const getRectFrom = this.getRectFromForPlaceholder();\n placeholder.attach({\n container: this.sortedList.list.parentElement,\n getRectFrom,\n onRemove: () => {\n if(this.placeholder === placeholder) {\n this.placeholder = undefined;\n }\n },\n blockScrollable: this.scrollable\n });\n\n return placeholder;\n }\n\n public loadDialogs(side: SliceSides) {\n /* if(testScroll) {\n return;\n } */\n\n const log = this.log.bindPrefix('load-' + getUnsafeRandomInt(1000, 9999));\n log('try', side);\n\n if(this.loadDialogsPromise || this.loadDialogsRenderPromise/* || 1 === 1 */) return this.loadDialogsPromise;\n else if(this.scrollable.loadedAll[side]) {\n return Promise.resolve({\n cached: true,\n renderPromise: Promise.resolve()\n });\n }\n\n log.warn('start', side);\n const middlewareError = makeError('MIDDLEWARE');\n\n const cachedInfoPromise = deferredPromise<boolean>();\n const renderPromise = new Promise<void>(async(resolve, reject) => {\n const chatList = this.sortedList.list;\n\n let placeholder = this.placeholder;\n try {\n const getConversationsResult = this.loadDialogsInner(side);\n const a = await getConversationsResult;\n\n if(\n !chatList.childElementCount &&\n !placeholder &&\n (\n (!this.loadedDialogsAtLeastOnce && this.needPlaceholderAtFirstTime) ||\n !a.cached\n )\n ) {\n if(this.loadDialogsRenderPromise !== renderPromise) {\n throw middlewareError;\n }\n\n placeholder = this.createPlaceholder();\n\n cachedInfoPromise.resolve(false);\n }\n\n const result = await a.result;\n // await pause(5000);\n if(this.loadDialogsRenderPromise !== renderPromise) {\n throw middlewareError;\n }\n\n cachedInfoPromise.resolve(a.cached);\n\n // console.timeEnd('getDialogs time');\n\n // * loaded all\n // if(!result.dialogs.length || chatList.childElementCount === result.count) {\n // !result.dialogs.length не подходит, так как при супердревном диалоге getConversations его не выдаст.\n // if(chatList.childElementCount === result.count) {\n if(side === 'bottom') {\n if(result.isEnd) {\n this.scrollable.loadedAll[side] = true;\n }\n } else if(result.isTopEnd) {\n this.scrollable.loadedAll[side] = true;\n }\n\n const length = result.dialogs.length;\n log(`will render ${length} dialogs`);\n if(length) {\n const dialogs = side === 'top' ? result.dialogs.slice().reverse() : result.dialogs;\n\n const loadPromises = dialogs.map((dialog) => {\n return this.sortedList.add(this.getDialogKey(dialog as T));\n });\n\n await Promise.all(loadPromises).catch();\n if(this.loadDialogsRenderPromise !== renderPromise) {\n throw middlewareError;\n }\n }\n\n const offsetDialog = result.dialogs[side === 'top' ? 0 : length - 1];\n if(offsetDialog) {\n this.offsets[side] = getDialogIndex(offsetDialog, this.indexKey);\n }\n\n // don't set it before - no need to fire length change with every dialog\n this.loadedDialogsAtLeastOnce = true;\n appDialogsManager.onListLengthChange();\n\n log('getDialogs', result, chatList.childElementCount);\n\n setTimeout(() => {\n this.scrollable.onScroll();\n }, 0);\n\n if(placeholder) {\n // await pause(500);\n placeholder.detach(chatList.childElementCount);\n }\n } catch(err) {\n if((err as ApiError)?.type !== 'MIDDLEWARE') {\n log.error(err);\n }\n\n reject(err);\n cachedInfoPromise.reject(err);\n return;\n }\n\n resolve();\n }).finally(() => {\n if(this.loadDialogsRenderPromise === renderPromise) {\n log('end');\n this.loadDialogsRenderPromise = undefined;\n } else {\n log('has been cleared');\n }\n });\n\n this.loadDialogsRenderPromise = renderPromise;\n const loadDialogsPromise = this.loadDialogsPromise = cachedInfoPromise.then((cached) => {\n return {\n cached,\n renderPromise\n };\n }).finally(() => {\n if(this.loadDialogsPromise === loadDialogsPromise) {\n this.loadDialogsPromise = undefined;\n }\n });\n\n return loadDialogsPromise;\n }\n\n public async setOffsets() {\n const chatList = this.sortedList.list;\n const [firstDialog, lastDialog] = await Promise.all([\n this.getDialogFromElement(chatList.firstElementChild as HTMLElement),\n this.getDialogFromElement(chatList.lastElementChild as HTMLElement)\n ]);\n\n const {indexKey} = this;\n this.offsets.top = getDialogIndex(firstDialog, indexKey);\n this.offsets.bottom = getDialogIndex(lastDialog, indexKey);\n }\n\n public getDialogKey(dialog: T): DialogKey {\n throw NOT_IMPLEMENTED_ERROR;\n }\n\n public getDialogKeyFromElement(element: HTMLElement): DialogKey {\n throw NOT_IMPLEMENTED_ERROR;\n }\n\n public getRectFromForPlaceholder(): Parameters<DialogsPlaceholder['attach']>[0]['getRectFrom'] {\n throw NOT_IMPLEMENTED_ERROR;\n }\n\n public getDialogFromElement(element: HTMLElement): Promise<T> {\n throw NOT_IMPLEMENTED_ERROR;\n }\n\n public loadDialogsInner(side: SliceSides): ReturnType<AppManagers['acknowledged']['dialogsStorage']['getDialogs']> {\n throw NOT_IMPLEMENTED_ERROR;\n }\n\n public async setTyping(dialog: T) {\n const key = this.getDialogKey(dialog);\n const dom = this.getDialogDom(key);\n if(!dom) {\n return;\n }\n\n const oldTypingElement = dom.lastMessageSpan.querySelector('.peer-typing-container') as HTMLElement;\n const newTypingElement = await appImManager.getPeerTyping(\n dialog.peerId,\n oldTypingElement,\n dialog._ === 'forumTopic' ? dialog.id : undefined\n );\n if(!oldTypingElement && newTypingElement) {\n replaceContent(dom.lastMessageSpan, newTypingElement);\n dom.lastMessageSpan.classList.add('user-typing');\n }\n }\n\n public unsetTyping(dialog: T) {\n const key = this.getDialogKey(dialog);\n const dialogElement = this.getDialogElement(key);\n if(!dialogElement) {\n return;\n }\n\n dialogElement.dom.lastMessageSpan.classList.remove('user-typing');\n appDialogsManager.setLastMessageN({\n dialog,\n lastMessage: null,\n dialogElement,\n setUnread: null\n });\n }\n\n public getDialogDom(key: DialogKey) {\n // return this.doms[peerId];\n const element = this.sortedList.get(key);\n return element?.dom;\n }\n\n public getDialogElement(key: DialogKey) {\n const element = this.sortedList.get(key);\n return element?.dialogElement;\n }\n\n public bindScrollable() {\n this.scrollable.container.addEventListener('scroll', this.onChatsRegularScroll);\n this.scrollable.onScrolledTop = this.onChatsScrollTop.bind(this);\n this.scrollable.onScrolledBottom = this.onChatsScroll.bind(this);\n this.scrollable.setVirtualContainer(this.sortedList.list);\n }\n\n public clear() {\n this.sortedList.clear();\n this.placeholder?.remove();\n }\n\n public reset() {\n this.scrollable.loadedAll.top = true;\n this.scrollable.loadedAll.bottom = false;\n this.offsets.top = this.offsets.bottom = 0;\n this.loadDialogsRenderPromise = undefined;\n this.loadDialogsPromise = undefined;\n }\n\n public fullReset() {\n this.reset();\n this.clear();\n return this.onChatsScroll();\n }\n\n public destroy() {\n this.clear();\n this.scrollable.destroy();\n this.listenerSetter.removeAll();\n }\n}\n\nclass Some3 extends Some<ForumTopic> {\n constructor(public peerId: PeerId, public paddingX: number) {\n super();\n\n this.placeholderOptions = {\n avatarSize: 0,\n marginVertical: 5,\n totalHeight: 64\n };\n\n this.listenerSetter.add(rootScope)('peer_typings', async({peerId, threadId, typings}) => {\n if(!threadId || this.peerId !== peerId) {\n return;\n }\n\n const dialog = await this.managers.dialogsStorage.getForumTopic(peerId, threadId);\n\n if(!dialog) return;\n\n if(typings.length) {\n this.setTyping(dialog);\n } else {\n this.unsetTyping(dialog);\n }\n });\n\n this.listenerSetter.add(rootScope)('dialogs_multiupdate', (dialogs) => {\n for(const [peerId, {dialog, topics}] of dialogs) {\n if(peerId !== this.peerId || !topics?.size) {\n continue;\n }\n\n topics.forEach((forumTopic) => {\n this.updateDialog(forumTopic);\n });\n }\n });\n\n this.listenerSetter.add(rootScope)('dialog_unread', ({dialog}) => {\n if(dialog?._ !== 'forumTopic' || dialog.peerId !== this.peerId) {\n return;\n }\n\n appDialogsManager.setUnreadMessagesN({dialog, dialogElement: this.getDialogElement(this.getDialogKey(dialog))});\n });\n\n this.listenerSetter.add(rootScope)('dialog_notify_settings', async(dialog) => {\n if(dialog.peerId !== this.peerId) {\n return;\n }\n\n if(dialog._ === 'dialog') {\n const all = this.sortedList.getAll();\n const entries = [...all.entries()];\n const promises = entries.map(([id]) => this.managers.dialogsStorage.getForumTopic(this.peerId, id));\n const topics = await Promise.all(promises);\n entries.forEach(([id, element], idx) => {\n appDialogsManager.setUnreadMessagesN({dialog: topics[idx], dialogElement: element.dialogElement}); // возможно это не нужно, но нужно менять is-muted\n });\n\n return;\n }\n\n appDialogsManager.setUnreadMessagesN({dialog, dialogElement: this.getDialogElement(this.getDialogKey(dialog))}); // возможно это не нужно, но нужно менять is-muted\n });\n\n this.listenerSetter.add(rootScope)('dialog_drop', (dialog) => {\n if(dialog._ !== 'forumTopic' || dialog.peerId !== this.peerId) {\n return;\n }\n\n this.deleteDialogByKey(this.getDialogKey(dialog));\n });\n\n this.listenerSetter.add(rootScope)('dialog_draft', ({dialog, drop, peerId}) => {\n if(dialog._ !== 'forumTopic' || dialog.peerId !== this.peerId) {\n return;\n }\n\n if(drop) {\n this.deleteDialog(dialog);\n } else {\n this.updateDialog(dialog);\n }\n });\n }\n\n protected isDialogMustBeInViewport(dialog: ForumTopic) {\n if(dialog.pFlags.hidden) return false;\n return super.isDialogMustBeInViewport(dialog);\n }\n\n public getDialogKey(dialog: ForumTopic) {\n return dialog.id;\n }\n\n public getDialogKeyFromElement(element: HTMLElement) {\n return +element.dataset.threadId;\n }\n\n public getRectFromForPlaceholder() {\n return (): DOMRectEditable => {\n const sidebarRect = appSidebarLeft.rect;\n const paddingY = 56;\n return {\n top: paddingY,\n right: sidebarRect.right,\n bottom: 0,\n left: this.paddingX,\n width: sidebarRect.width - this.paddingX,\n height: sidebarRect.height - paddingY\n };\n };\n }\n\n public getDialogFromElement(element: HTMLElement) {\n return this.managers.dialogsStorage.getForumTopic(+element.dataset.peerId, +element.dataset.threadId);\n }\n\n public async loadDialogsInner(side: SliceSides) {\n const {indexKey} = this;\n let loadCount = windowSize.height / 64 * 1.25 | 0;\n let offsetIndex = 0;\n\n const filterId = this.peerId;\n const {index: currentOffsetIndex} = this.getOffsetIndex(side);\n offsetIndex = currentOffsetIndex;\n if(currentOffsetIndex) {\n if(side === 'top') {\n const storage = await this.managers.dialogsStorage.getFolderDialogs(filterId, true);\n const index = storage.findIndex((dialog) => getDialogIndex(dialog, indexKey) <= currentOffsetIndex);\n const needIndex = Math.max(0, index - loadCount);\n loadCount = index - needIndex;\n offsetIndex = getDialogIndex(storage[needIndex], indexKey) + 1;\n } else {\n offsetIndex = currentOffsetIndex;\n }\n }\n\n return this.managers.acknowledged.dialogsStorage.getDialogs({\n offsetIndex,\n limit: loadCount,\n filterId,\n skipMigrated: true\n });\n }\n}\n\nclass Some2 extends Some<Dialog> {\n constructor(protected filterId: number) {\n super();\n\n this.needPlaceholderAtFirstTime = true;\n\n this.listenerSetter.add(rootScope)('peer_typings', async({peerId, typings}) => {\n const [dialog, isForum] = await Promise.all([\n this.managers.appMessagesManager.getDialogOnly(peerId),\n this.managers.appPeersManager.isForum(peerId)\n ]);\n\n if(!dialog || isForum) return;\n\n if(typings.length) {\n this.setTyping(dialog);\n } else {\n this.unsetTyping(dialog);\n }\n });\n\n this.listenerSetter.add(rootScope)('user_update', async(userId) => {\n if(!this.isActive) {\n return;\n }\n\n const peerId = userId.toPeerId();\n const dom = this.getDialogDom(peerId);\n if(!dom) {\n return;\n }\n\n const status = await this.managers.appUsersManager.getUserStatus(userId);\n const online = status?._ === 'userStatusOnline';\n this.setOnlineStatus(dom.avatarEl, online);\n });\n\n this.listenerSetter.add(rootScope)('chat_update', async(chatId) => {\n const peerId = chatId.toPeerId(true);\n this.processDialogForCallStatus(peerId);\n });\n\n this.listenerSetter.add(rootScope)('dialog_flush', ({dialog}) => {\n if(!this.isActive || !dialog) {\n return;\n }\n\n appDialogsManager.setLastMessageN({\n dialog,\n setUnread: true\n });\n this.validateDialogForFilter(dialog);\n });\n\n this.listenerSetter.add(rootScope)('dialogs_multiupdate', (dialogs) => {\n if(!this.isActive) {\n return;\n }\n\n for(const [peerId, {dialog, topics}] of dialogs) {\n if(dialog?._ !== 'dialog') {\n continue;\n }\n\n this.updateDialog(dialog);\n\n appDialogsManager.processContact?.(peerId.toPeerId());\n\n this.validateDialogForFilter(dialog);\n }\n });\n\n this.listenerSetter.add(rootScope)('dialog_drop', (dialog) => {\n if(!this.isActive || dialog._ !== 'dialog') {\n return;\n }\n\n this.deleteDialogByKey(dialog.peerId);\n appDialogsManager.processContact?.(dialog.peerId);\n });\n\n this.listenerSetter.add(rootScope)('dialog_unread', ({dialog}) => {\n if(!this.isActive || dialog?._ !== 'dialog') {\n return;\n }\n\n appDialogsManager.setUnreadMessagesN({dialog, dialogElement: this.getDialogElement(this.getDialogKey(dialog))});\n this.validateDialogForFilter(dialog);\n });\n\n this.listenerSetter.add(rootScope)('dialog_notify_settings', (dialog) => {\n if(!this.isActive || dialog._ === 'forumTopic') {\n return;\n }\n\n this.validateDialogForFilter(dialog);\n appDialogsManager.setUnreadMessagesN({dialog, dialogElement: this.getDialogElement(this.getDialogKey(dialog))}); // возможно это не нужно, но нужно менять is-muted\n });\n\n this.listenerSetter.add(rootScope)('dialog_draft', ({dialog, drop, peerId}) => {\n if(!this.isActive || dialog._ === 'forumTopic') {\n return;\n }\n\n if(drop) {\n this.deleteDialog(dialog);\n } else {\n this.updateDialog(dialog);\n }\n\n appDialogsManager.processContact?.(peerId);\n });\n\n this.listenerSetter.add(rootScope)('filter_update', async(filter) => {\n if(this.isActive && filter.id === this.filterId && !REAL_FOLDERS.has(filter.id)) {\n const dialogs = await this.managers.dialogsStorage.getCachedDialogs(true);\n await this.validateListForFilter();\n for(let i = 0, length = dialogs.length; i < length; ++i) {\n const dialog = dialogs[i];\n this.updateDialog(dialog);\n }\n }\n });\n }\n\n private get isActive() {\n return appDialogsManager.xd === this;\n }\n\n public getRectFromForPlaceholder() {\n return this.filterId === FOLDER_ID_ARCHIVE ? appDialogsManager.chatsContainer : appDialogsManager.folders.container;\n }\n\n public async loadDialogsInner(side: SliceSides) {\n const {filterId, indexKey} = this;\n let loadCount = windowSize.height / 72 * 1.25 | 0;\n let offsetIndex = 0;\n\n const doNotRenderChatList = appDialogsManager.doNotRenderChatList; // cache before awaits\n\n const {index: currentOffsetIndex} = this.getOffsetIndex(side);\n if(currentOffsetIndex) {\n if(side === 'top') {\n const storage = await this.managers.dialogsStorage.getFolderDialogs(filterId, true);\n const index = storage.findIndex((dialog) => getDialogIndex(dialog, indexKey) <= currentOffsetIndex);\n const needIndex = Math.max(0, index - loadCount);\n loadCount = index - needIndex;\n offsetIndex = getDialogIndex(storage[needIndex], indexKey) + 1;\n } else {\n offsetIndex = currentOffsetIndex;\n }\n }\n\n const promise = this.managers.acknowledged.dialogsStorage.getDialogs({\n offsetIndex,\n limit: loadCount,\n filterId,\n skipMigrated: true\n });\n\n const a = await promise;\n if(doNotRenderChatList) {\n a.result = Promise.reject(makeError('MIDDLEWARE'));\n }\n\n return a;\n }\n\n public setOnlineStatus(element: HTMLElement, online: boolean) {\n const className = 'is-online';\n const hasClassName = element.classList.contains(className);\n !hasClassName && online && element.classList.add(className);\n SetTransition({\n element: element,\n className: 'is-visible',\n forwards: online,\n duration: 250,\n onTransitionEnd: online ? undefined : () => {\n element.classList.remove(className);\n },\n useRafs: online && !hasClassName ? 2 : 0\n });\n }\n\n public generateScrollable(list: HTMLUListElement, filter: Parameters<AppDialogsManager['addFilter']>[0]) {\n const filterId = filter.id;\n const scrollable = new Scrollable(null, 'CL', 500);\n scrollable.container.dataset.filterId = '' + filterId;\n\n const indexKey = getDialogIndexKey(filter.localId);\n const sortedDialogList = new SortedDialogList({\n managers: rootScope.managers,\n log: this.log,\n list: list,\n indexKey,\n onListLengthChange: appDialogsManager.onListLengthChange\n });\n\n this.scrollable = scrollable;\n this.sortedList = sortedDialogList;\n this.setIndexKey(indexKey);\n this.bindScrollable();\n\n // list.classList.add('hide');\n // scrollable.container.style.backgroundColor = '#' + (Math.random() * (16 ** 6 - 1) | 0).toString(16);\n\n return scrollable;\n }\n\n public testDialogForFilter(dialog: Dialog) {\n if(!REAL_FOLDERS.has(this.filterId) ? getDialogIndex(dialog, this.indexKey) === undefined : this.filterId !== dialog.folder_id) {\n return false;\n }\n\n return true;\n }\n\n protected isDialogMustBeInViewport(dialog: Dialog) {\n if(dialog.migratedTo !== undefined || !this.testDialogForFilter(dialog)) return false;\n return super.isDialogMustBeInViewport(dialog);\n }\n\n /**\n * Удалит неподходящие чаты из списка, но не добавит их(!)\n */\n public async validateListForFilter() {\n this.sortedList.getAll().forEach(async(element) => {\n const dialog = await rootScope.managers.appMessagesManager.getDialogOnly(element.id);\n if(!this.testDialogForFilter(dialog)) {\n this.deleteDialog(dialog);\n }\n });\n }\n\n /**\n * Удалит неподходящий чат из списка, но не добавит его(!)\n */\n public validateDialogForFilter(dialog: Dialog) {\n if(!this.getDialogElement(dialog.peerId)) {\n return;\n }\n\n if(!this.testDialogForFilter(dialog)) {\n this.deleteDialog(dialog);\n }\n }\n\n public setCallStatus(dom: DialogDom, visible: boolean) {\n let {callIcon, listEl} = dom;\n if(!callIcon && visible) {\n const {canvas, startAnimation} = dom.callIcon = callIcon = groupCallActiveIcon(listEl.classList.contains('active'));\n canvas.classList.add('dialog-group-call-icon');\n listEl.append(canvas);\n startAnimation();\n }\n\n if(!callIcon) {\n return;\n }\n\n SetTransition({\n element: dom.callIcon.canvas,\n className: 'is-visible',\n forwards: visible,\n duration: BADGE_TRANSITION_TIME,\n onTransitionEnd: visible ? undefined : () => {\n dom.callIcon.canvas.remove();\n dom.callIcon = undefined;\n },\n useRafs: visible ? 2 : 0\n });\n }\n\n public async processDialogForCallStatus(peerId: PeerId, dom?: DialogDom) {\n if(!IS_GROUP_CALL_SUPPORTED) {\n return;\n }\n\n if(!dom) dom = this.getDialogDom(peerId);\n if(!dom) return;\n\n const chat = await rootScope.managers.appChatsManager.getChat(peerId.toChatId()) as Chat.chat | Chat.channel;\n this.setCallStatus(dom, !!(chat.pFlags.call_active && chat.pFlags.call_not_empty));\n }\n\n public onChatsScroll(side: SliceSides = 'bottom') {\n if(this.scrollable.loadedAll[side]) {\n appDialogsManager.loadContacts?.();\n }\n\n this.log('onChatsScroll', side);\n return super.onChatsScroll(side);\n }\n\n public toggleAvatarUnreadBadges(value: boolean, useRafs: number) {\n if(!value) {\n this.sortedList.getAll().forEach((sortedDialog) => {\n const {dom, dialogElement} = sortedDialog;\n if(!dom.unreadAvatarBadge) {\n return;\n }\n\n dialogElement.toggleBadgeByKey('unreadAvatarBadge', false, false, false);\n });\n\n return;\n }\n\n const reuseClassNames = ['unread', 'mention'];\n this.sortedList.getAll().forEach((sortedDialog) => {\n const {dom, dialogElement} = sortedDialog;\n const unreadContent = dom.unreadBadge?.textContent;\n if(!unreadContent || dom.unreadBadge.classList.contains('backwards')) {\n return;\n }\n\n const isUnreadAvatarBadgeMounted = !!dom.unreadAvatarBadge;\n dialogElement.createUnreadAvatarBadge();\n dialogElement.toggleBadgeByKey('unreadAvatarBadge', true, isUnreadAvatarBadgeMounted);\n dom.unreadAvatarBadge.textContent = unreadContent;\n const unreadAvatarBadgeClassList = dom.unreadAvatarBadge.classList;\n const unreadBadgeClassList = dom.unreadBadge.classList;\n reuseClassNames.forEach((className) => {\n unreadAvatarBadgeClassList.toggle(className, unreadBadgeClassList.contains(className));\n });\n });\n }\n\n public getDialogKey(dialog: Dialog) {\n return dialog.peerId;\n }\n\n public getDialogKeyFromElement(element: HTMLElement) {\n return +element.dataset.peerId;\n }\n\n public getDialogFromElement(element: HTMLElement) {\n return rootScope.managers.appMessagesManager.getDialogOnly(element.dataset.peerId.toPeerId());\n }\n}\n\n// const testScroll = false;\n// let testTopSlice = 1;\n\nexport class AppDialogsManager {\n public chatsContainer = document.getElementById('chatlist-container') as HTMLDivElement;\n\n private log = logger('DIALOGS', LogTypes.Log | LogTypes.Error | LogTypes.Warn | LogTypes.Debug);\n\n private contextMenu: DialogsContextMenu;\n\n public filterId: number;\n public folders: {[k in 'menu' | 'container' | 'menuScrollContainer']: HTMLElement} = {\n menu: document.getElementById('folders-tabs'),\n menuScrollContainer: null,\n container: document.getElementById('folders-container')\n };\n private filtersRendered: {\n [filterId: string]: {\n menu: HTMLElement,\n container: HTMLElement,\n unread: HTMLElement,\n title: HTMLElement\n }\n } = {};\n private showFiltersPromise: Promise<void>;\n\n private lastActiveElements: Set<HTMLElement> = new Set();\n\n public loadContacts: () => void;\n public processContact: (peerId: PeerId) => void;\n\n private initedListeners = false;\n\n public onListLengthChange: () => Promise<void>;\n private allChatsIntlElement: I18n.IntlElement;\n\n private emptyDialogsPlaceholderSubtitle: I18n.IntlElement;\n private updateContactsLengthPromise: Promise<number>;\n\n private filtersNavigationItem: NavigationItem;\n\n private managers: AppManagers;\n private selectTab: ReturnType<typeof horizontalMenu>;\n\n public doNotRenderChatList: boolean;\n\n private stateMiddlewareHelper: MiddlewareHelper;\n\n private forumsTabs: Map<PeerId, ForumTab>;\n private forumsSlider: HTMLElement;\n public forumTab: ForumTab;\n private forumNavigationItem: NavigationItem;\n\n public xd: Some2;\n public xds: {[filterId: number]: Some2} = {};\n\n public start() {\n const managers = this.managers = getProxiedManagers();\n\n this.contextMenu = new DialogsContextMenu(managers);\n this.stateMiddlewareHelper = getMiddleware();\n\n this.folders.menuScrollContainer = this.folders.menu.parentElement;\n\n this.onListLengthChange = debounce(this._onListLengthChange, 100, false, true);\n\n const bottomPart = document.createElement('div');\n bottomPart.classList.add('connection-status-bottom');\n bottomPart.append(this.folders.container);\n\n this.forumsTabs = new Map();\n this.forumsSlider = document.createElement('div');\n this.forumsSlider.classList.add('topics-slider');\n this.chatsContainer.parentElement.parentElement.append(this.forumsSlider);\n // findUpClassName(this.chatsContainer, 'chatlist-container').append(this.forumsSlider);\n\n // appSidebarLeft.onOpenTab = () => {\n // return this.toggleForumTab();\n // };\n\n /* if(isTouchSupported && isSafari) {\n let allowUp: boolean, allowDown: boolean, slideBeginY: number;\n const container = this.scroll.container;\n container.addEventListener('touchstart', (event) => {\n allowUp = container.scrollTop > 0;\n allowDown = (container.scrollTop < container.scrollHeight - container.clientHeight);\n // @ts-ignore\n slideBeginY = event.pageY;\n });\n\n container.addEventListener('touchmove', (event: any) => {\n var up = (event.pageY > slideBeginY);\n var down = (event.pageY < slideBeginY);\n slideBeginY = event.pageY;\n if((up && allowUp) || (down && allowDown)) {\n event.stopPropagation();\n } else if(up || down) {\n event.preventDefault();\n }\n });\n } */\n\n if(IS_TOUCH_SUPPORTED) {\n handleTabSwipe({\n element: this.folders.container,\n onSwipe: (xDiff) => {\n const prevId = selectTab.prevId();\n selectTab(xDiff < 0 ? prevId + 1 : prevId - 1);\n },\n verifyTouchTarget: () => {\n return !this.forumTab;\n }\n });\n }\n\n this.allChatsIntlElement = new I18n.IntlElement({\n key: 'FilterAllChatsShort'\n });\n\n rootScope.addEventListener('premium_toggle', async(isPremium) => {\n if(isPremium) {\n return;\n }\n\n const isFolderAvailable = await this.managers.filtersStorage.isFilterIdAvailable(this.filterId);\n if(!isFolderAvailable) {\n selectTab(whichChild(this.filtersRendered[FOLDER_ID_ALL].menu), false);\n }\n });\n\n rootScope.addEventListener('state_cleared', () => {\n const clearCurrent = REAL_FOLDERS.has(this.filterId);\n // setTimeout(() =>\n apiManagerProxy.getState().then(async(state) => {\n this.xd.loadedDialogsAtLeastOnce = false;\n this.showFiltersPromise = undefined;\n\n /* const clearPromises: Promise<any>[] = [];\n for(const name in this.managers.appStateManager.storagesResults) {\n const results = this.managers.appStateManager.storagesResults[name as keyof AppStateManager['storages']];\n const storage = this.managers.appStateManager.storages[name as keyof AppStateManager['storages']];\n results.length = 0;\n clearPromises.push(storage.clear());\n } */\n\n if(clearCurrent) {\n this.xd.clear();\n this.onTabChange();\n }\n\n this.onStateLoaded(state);\n })// , 5000);\n });\n\n this.setFilterId(FOLDER_ID_ALL, FOLDER_ID_ALL);\n this.addFilter({\n id: FOLDER_ID_ALL,\n title: '',\n localId: FOLDER_ID_ALL\n });\n\n const foldersScrollable = new ScrollableX(this.folders.menuScrollContainer);\n bottomPart.prepend(this.folders.menuScrollContainer);\n const selectTab = this.selectTab = horizontalMenu(this.folders.menu, this.folders.container, async(id, tabContent) => {\n /* if(id !== 0) {\n id += 1;\n } */\n\n const _id = id;\n id = +tabContent.dataset.filterId || FOLDER_ID_ALL;\n\n const isFilterAvailable = this.filterId === -1 || REAL_FOLDERS.has(id) || await this.managers.filtersStorage.isFilterIdAvailable(id);\n if(!isFilterAvailable) {\n return false;\n }\n\n const wasFilterId = this.filterId;\n if(!IS_MOBILE_SAFARI) {\n if(_id) {\n if(!this.filtersNavigationItem) {\n this.filtersNavigationItem = {\n type: 'filters',\n onPop: () => {\n selectTab(0);\n this.filtersNavigationItem = undefined;\n }\n };\n\n appNavigationController.spliceItems(1, 0, this.filtersNavigationItem);\n }\n } else if(this.filtersNavigationItem) {\n appNavigationController.removeItem(this.filtersNavigationItem);\n this.filtersNavigationItem = undefined;\n }\n }\n\n if(wasFilterId === id) return;\n\n this.xds[id].clear();\n const promise = this.setFilterIdAndChangeTab(id).then(({cached, renderPromise}) => {\n if(cached) {\n return renderPromise;\n }\n });\n\n if(wasFilterId !== -1) {\n return promise;\n }\n }, () => {\n for(const folderId in this.xds) {\n if(+folderId !== this.filterId) {\n this.xds[folderId].clear();\n }\n }\n }, undefined, foldersScrollable);\n\n apiManagerProxy.getState().then((state) => {\n // * it should've had a better place :(\n appMediaPlaybackController.setPlaybackParams(state.playbackParams);\n appMediaPlaybackController.addEventListener('playbackParams', (params) => {\n this.managers.appStateManager.pushToState('playbackParams', params);\n });\n\n return this.onStateLoaded(state);\n })/* .then(() => {\n const isLoadedMain = this.managers.appMessagesManager.dialogsStorage.isDialogsLoaded(0);\n const isLoadedArchive = this.managers.appMessagesManager.dialogsStorage.isDialogsLoaded(1);\n const wasLoaded = isLoadedMain || isLoadedArchive;\n const a: Promise<any> = isLoadedMain ? Promise.resolve() : this.managers.appMessagesManager.getConversationsAll('', 0);\n const b: Promise<any> = isLoadedArchive ? Promise.resolve() : this.managers.appMessagesManager.getConversationsAll('', 1);\n a.finally(() => {\n b.then(() => {\n if(wasLoaded) {\n (apiUpdatesManager.updatesState.syncLoading || Promise.resolve()).then(() => {\n this.managers.appMessagesManager.refreshConversations();\n });\n }\n });\n });\n }) */;\n\n mediaSizes.addEventListener('resize', () => {\n this.changeFiltersAllChatsKey();\n });\n\n new ConnectionStatusComponent(this.managers, this.chatsContainer);\n this.chatsContainer.append(bottomPart);\n\n setTimeout(() => {\n lottieLoader.loadLottieWorkers();\n }, 200);\n\n PopupElement.MANAGERS = rootScope.managers = managers;\n appDownloadManager.construct(managers);\n appSidebarLeft.construct(managers);\n appSidebarRight.construct(managers);\n groupCallsController.construct(managers);\n callsController.construct(managers);\n appImManager.construct(managers);\n\n // start\n\n this.xd = this.xds[this.filterId];\n\n // selectTab(0, false);\n }\n\n public get chatList() {\n return this.xd.sortedList.list;\n }\n\n public setFilterId(filterId: number, localId: MyDialogFilter['localId']) {\n this.filterId = filterId;\n }\n\n public async setFilterIdAndChangeTab(filterId: number) {\n this.filterId = filterId;\n return this.onTabChange();\n }\n\n private initListeners() {\n rootScope.addEventListener('dialog_flush', ({dialog}) => {\n if(!dialog) {\n return;\n }\n\n this.setFiltersUnreadCount();\n });\n\n rootScope.addEventListener('folder_unread', async(folder) => {\n if(folder.id < 0) {\n const dialogElement = this.xd.getDialogElement(folder.id);\n if(!dialogElement) {\n return;\n }\n\n this.setUnreadMessagesN({\n dialog: await this.managers.dialogsStorage.getDialogOnly(folder.id),\n dialogElement\n });\n } else {\n this.setFilterUnreadCount(folder.id);\n }\n });\n\n rootScope.addEventListener('contacts_update', (userId) => {\n this.processContact?.(userId.toPeerId());\n });\n\n appImManager.addEventListener('peer_changed', ({peerId, threadId, isForum}) => {\n const options: Parameters<AppImManager['isSamePeer']>[0] = {peerId, threadId: isForum ? threadId : undefined};\n // const perf = performance.now();\n for(const element of this.lastActiveElements) {\n const elementThreadId = +element.dataset.threadId || undefined;\n const elementPeerId = element.dataset.peerId.toPeerId();\n if(!appImManager.isSamePeer({peerId: elementPeerId, threadId: elementThreadId}, options)) {\n this.setDialogActive(element, false);\n }\n }\n\n const elements = Array.from(document.querySelectorAll(`[data-autonomous=\"0\"] .chatlist-chat[data-peer-id=\"${peerId}\"]`)) as HTMLElement[];\n elements.forEach((element) => {\n const elementThreadId = +element.dataset.threadId || undefined;\n if(appImManager.isSamePeer({peerId, threadId: elementThreadId}, options)) {\n this.setDialogActive(element, true);\n }\n });\n // this.log('peer_changed total time:', performance.now() - perf);\n });\n\n rootScope.addEventListener('filter_update', async(filter) => {\n if(REAL_FOLDERS.has(filter.id)) {\n return;\n }\n\n if(!this.filtersRendered[filter.id]) {\n this.addFilter(filter);\n return;\n }\n\n const elements = this.filtersRendered[filter.id];\n setInnerHTML(elements.title, wrapEmojiText(filter.title));\n });\n\n rootScope.addEventListener('filter_delete', (filter) => {\n const elements = this.filtersRendered[filter.id];\n if(!elements) return;\n\n // set tab\n // (this.folders.menu.firstElementChild.children[Math.max(0, filter.id - 2)] as HTMLElement).click();\n elements.container.remove();\n elements.menu.remove();\n\n this.xds[filter.id].destroy();\n delete this.xds[filter.id];\n delete this.filtersRendered[filter.id];\n\n this.onFiltersLengthChange();\n\n if(this.filterId === filter.id) {\n this.selectTab(0, false);\n }\n });\n\n rootScope.addEventListener('filter_order', async(order) => {\n order = order.slice();\n indexOfAndSplice(order, FOLDER_ID_ARCHIVE);\n\n const containerToAppend = this.folders.menu as HTMLElement;\n const r = await Promise.all(order.map(async(filterId) => {\n const [indexKey, filter] = await Promise.all([\n this.managers.dialogsStorage.getDialogIndexKeyByFilterId(filterId),\n this.managers.filtersStorage.getFilter(filterId)\n ]);\n\n return {indexKey, filter};\n }));\n\n order.forEach((filterId, idx) => {\n const {indexKey, filter} = r[idx];\n const renderedFilter = this.filtersRendered[filterId];\n\n this.xds[filterId].setIndexKey(indexKey);\n\n positionElementByIndex(renderedFilter.menu, containerToAppend, filter.localId);\n positionElementByIndex(renderedFilter.container, this.folders.container, filter.localId);\n });\n\n /* if(this.filterId) {\n const tabIndex = order.indexOf(this.filterId) + 1;\n selectTab.prevId = tabIndex;\n } */\n });\n }\n\n public setDialogActive(listEl: HTMLElement, active: boolean) {\n const dom = (listEl as any).dialogDom as DialogDom;\n listEl.classList.toggle('active', active);\n listEl.classList.toggle('is-forum-open', this.forumTab?.peerId === listEl.dataset.peerId.toPeerId() && !listEl.dataset.threadId);\n if(active) {\n this.lastActiveElements.add(listEl);\n } else {\n this.lastActiveElements.delete(listEl);\n }\n\n if(dom?.callIcon) {\n dom.callIcon.setActive(active);\n }\n }\n\n private async onStateLoaded(state: State) {\n this.stateMiddlewareHelper.clean();\n const middleware = this.stateMiddlewareHelper.get();\n const filtersArr = state.filtersArr;\n const haveFilters = filtersArr.length > REAL_FOLDERS.size;\n // const filter = filtersArr.find((filter) => filter.id !== FOLDER_ID_ARCHIVE);\n\n const addFilters = (filters: MyDialogFilter[]) => {\n for(const filter of filters) {\n this.addFilter(filter);\n }\n };\n\n let addFiltersPromise: Promise<any>;\n if(haveFilters) {\n addFilters(filtersArr);\n } else {\n addFiltersPromise = this.managers.filtersStorage.getDialogFilters().then(addFilters);\n }\n\n this.doNotRenderChatList = true;\n const loadDialogsPromise = this.xd.onChatsScroll();\n const m = middlewarePromise(middleware);\n try {\n await m(loadDialogsPromise);\n } catch(err) {\n\n }\n\n // show the placeholder before the filters, and then will reset to the default tab again\n if(!haveFilters) {\n this.selectTab(0, false);\n }\n\n addFiltersPromise && await m(addFiltersPromise);\n // this.folders.menu.children[0].classList.add('active');\n\n this.doNotRenderChatList = undefined;\n\n this.filterId = -1;\n this.selectTab(0, false);\n\n if(!this.initedListeners) {\n this.initListeners();\n this.initedListeners = true;\n }\n\n haveFilters && this.showFiltersPromise && await m(this.showFiltersPromise);\n\n this.managers.appNotificationsManager.getNotifyPeerTypeSettings();\n\n await (await m(loadDialogsPromise)).renderPromise.catch(noop);\n this.managers.appMessagesManager.fillConversations();\n }\n\n /* private getOffset(side: 'top' | 'bottom'): {index: number, pos: number} {\n if(!this.scroll.loadedAll[side]) {\n const element = (side === 'top' ? this.chatList.firstElementChild : this.chatList.lastElementChild) as HTMLElement;\n if(element) {\n const peerId = element.dataset.peerId;\n const dialog = this.managers.appMessagesManager.getDialogByPeerId(peerId);\n return {index: dialog[0].index, pos: dialog[1]};\n }\n }\n\n return {index: 0, pos: -1};\n } */\n\n public onTabChange = () => {\n this.xd = this.xds[this.filterId];\n this.xd.reset();\n return this.xd.onChatsScroll();\n };\n\n private async setFilterUnreadCount(filterId: number) {\n // if(filterId === FOLDER_ID_ALL) {\n // return;\n // }\n\n const unreadSpan = this.filtersRendered[filterId]?.unread;\n if(!unreadSpan) {\n return;\n }\n\n const {unreadUnmutedCount, unreadCount} = await this.managers.dialogsStorage.getFolderUnreadCount(filterId);\n\n unreadSpan.classList.toggle('badge-gray', !unreadUnmutedCount);\n const count = filterId === FOLDER_ID_ALL ? unreadUnmutedCount : unreadCount;\n unreadSpan.innerText = count ? '' + count : '';\n }\n\n private setFiltersUnreadCount() {\n for(const filterId in this.filtersRendered) {\n this.setFilterUnreadCount(+filterId);\n }\n }\n\n public l(filter: Parameters<AppDialogsManager['addFilter']>[0]) {\n const ul = this.createChatList();\n const xd = this.xds[filter.id] = new Some2(filter.id);\n const scrollable = xd.generateScrollable(ul, filter);\n this.setListClickListener(ul, null, true);\n\n return {ul, xd, scrollable};\n }\n\n private addFilter(filter: Pick<DialogFilter, 'title' | 'id' | 'localId'>) {\n if(filter.id === FOLDER_ID_ARCHIVE) {\n return;\n }\n\n const containerToAppend = this.folders.menu as HTMLElement;\n const renderedFilter = this.filtersRendered[filter.id];\n if(renderedFilter) {\n positionElementByIndex(renderedFilter.menu, containerToAppend, filter.localId);\n positionElementByIndex(renderedFilter.container, this.folders.container, filter.localId);\n return;\n }\n\n const menuTab = document.createElement('div');\n menuTab.classList.add('menu-horizontal-div-item');\n const span = document.createElement('span');\n const titleSpan = document.createElement('span');\n titleSpan.classList.add('text-super');\n if(filter.id === FOLDER_ID_ALL) titleSpan.append(this.allChatsIntlElement.element);\n else setInnerHTML(titleSpan, wrapEmojiText(filter.title));\n const unreadSpan = document.createElement('div');\n unreadSpan.classList.add('badge', 'badge-20', 'badge-primary');\n const i = document.createElement('i');\n span.append(titleSpan, unreadSpan, i);\n ripple(menuTab);\n menuTab.append(span);\n\n menuTab.dataset.filterId = '' + filter.id;\n\n positionElementByIndex(menuTab, containerToAppend, filter.localId);\n // containerToAppend.append(li);\n\n const {ul, scrollable} = this.l(filter);\n scrollable.container.classList.add('tabs-tab', 'chatlist-parts');\n\n /* const parts = document.createElement('div');\n parts.classList.add('chatlist-parts'); */\n\n const top = document.createElement('div');\n top.classList.add('chatlist-top');\n\n const bottom = document.createElement('div');\n bottom.classList.add('chatlist-bottom');\n\n top.append(ul);\n scrollable.container.append(top, bottom);\n /* parts.append(top, bottom);\n scrollable.container.append(parts); */\n\n const div = scrollable.container;\n // this.folders.container.append(div);\n positionElementByIndex(scrollable.container, this.folders.container, filter.localId);\n\n this.filtersRendered[filter.id] = {\n menu: menuTab,\n container: div,\n unread: unreadSpan,\n title: titleSpan\n };\n\n this.onFiltersLengthChange();\n }\n\n private changeFiltersAllChatsKey() {\n const scrollable = this.folders.menuScrollContainer.firstElementChild;\n const key: LangPackKey = scrollable.scrollWidth > scrollable.clientWidth ? 'FilterAllChatsShort' : 'FilterAllChats';\n this.allChatsIntlElement.compareAndUpdate({key});\n }\n\n private onFiltersLengthChange() {\n let promise = this.showFiltersPromise;\n return promise ??= this.showFiltersPromise = pause(0).then(() => {\n if(this.showFiltersPromise !== promise) {\n return;\n }\n\n const length = Object.keys(this.filtersRendered).length;\n const show = length > 1;\n const wasShowing = !this.folders.menuScrollContainer.classList.contains('hide');\n\n if(show !== wasShowing) {\n this.folders.menuScrollContainer.classList.toggle('hide', !show);\n if(show && !wasShowing) {\n this.setFiltersUnreadCount();\n }\n\n this.chatsContainer.classList.toggle('has-filters', show);\n }\n\n this.changeFiltersAllChatsKey();\n\n this.showFiltersPromise = undefined;\n });\n }\n\n private generateEmptyPlaceholder(options: {\n title: LangPackKey,\n subtitle?: LangPackKey,\n subtitleArgs?: FormatterArguments,\n classNameType: string\n }) {\n const BASE_CLASS = 'empty-placeholder';\n const container = document.createElement('div');\n container.classList.add(BASE_CLASS, BASE_CLASS + '-' + options.classNameType);\n\n const header = document.createElement('div');\n header.classList.add(BASE_CLASS + '-header');\n _i18n(header, options.title);\n\n const subtitle = document.createElement('div');\n subtitle.classList.add(BASE_CLASS + '-subtitle');\n if(options.subtitle) {\n _i18n(subtitle, options.subtitle, options.subtitleArgs);\n }\n\n container.append(header, subtitle);\n\n return {container, header, subtitle};\n }\n\n private checkIfPlaceholderNeeded() {\n if(this.filterId === FOLDER_ID_ARCHIVE) {\n return;\n }\n\n const chatList = this.chatList;\n const part = chatList.parentElement as HTMLElement;\n let placeholderContainer = (Array.from(part.children) as HTMLElement[]).find((el) => el.matches('.empty-placeholder'));\n const needPlaceholder = this.xd.scrollable.loadedAll.bottom && !chatList.childElementCount/* || true */;\n // chatList.style.display = 'none';\n\n if(needPlaceholder && placeholderContainer) {\n return;\n } else if(!needPlaceholder) {\n if(placeholderContainer) {\n part.classList.remove('with-placeholder');\n placeholderContainer.remove();\n }\n\n return;\n }\n\n let placeholder: ReturnType<AppDialogsManager['generateEmptyPlaceholder']>, type: 'dialogs' | 'folder';\n if(!this.filterId) {\n placeholder = this.generateEmptyPlaceholder({\n title: 'ChatList.Main.EmptyPlaceholder.Title',\n classNameType: type = 'dialogs'\n });\n\n placeholderContainer = placeholder.container;\n\n const img = document.createElement('img');\n img.classList.add('empty-placeholder-dialogs-icon');\n\n this.emptyDialogsPlaceholderSubtitle = new I18n.IntlElement({\n element: placeholder.subtitle\n });\n\n Promise.all([\n this.updateContactsLength(false),\n renderImageFromUrlPromise(img, 'assets/img/EmptyChats.svg'),\n fastRafPromise()\n ]).then(([usersLength]) => {\n placeholderContainer.classList.add('visible');\n part.classList.toggle('has-contacts', !!usersLength);\n });\n\n placeholderContainer.prepend(img);\n } else {\n placeholder = this.generateEmptyPlaceholder({\n title: 'FilterNoChatsToDisplay',\n subtitle: 'FilterNoChatsToDisplayInfo',\n classNameType: type = 'folder'\n });\n\n placeholderContainer = placeholder.container;\n\n const div = document.createElement('div');\n const emoji = '📂';\n const size = 128;\n wrapStickerEmoji({\n div,\n emoji: emoji,\n width: size,\n height: size\n });\n\n placeholderContainer.prepend(div);\n\n const button = Button('btn-primary btn-color-primary btn-control tgico', {\n text: 'FilterHeaderEdit',\n icon: 'settings'\n });\n\n attachClickEvent(button, async() => {\n const tab = appSidebarLeft.createTab(AppEditFolderTab);\n tab.setInitFilter(await this.managers.filtersStorage.getFilter(this.filterId));\n tab.open();\n });\n\n placeholderContainer.append(button);\n }\n\n part.append(placeholderContainer);\n part.classList.add('with-placeholder');\n part.dataset.placeholderType = type;\n }\n\n private updateContactsLength(updatePartClassName: boolean) {\n return this.updateContactsLengthPromise ??= this.managers.appUsersManager.getContacts().then((users) => {\n const subtitle = this.emptyDialogsPlaceholderSubtitle;\n if(subtitle) {\n let key: LangPackKey, args: FormatterArguments;\n\n if(users.length/* && false */) {\n key = 'ChatList.Main.EmptyPlaceholder.Subtitle';\n args = [i18n('Contacts.Count', [users.length])];\n } else {\n key = 'ChatList.Main.EmptyPlaceholder.SubtitleNoContacts';\n args = [];\n }\n\n subtitle.compareAndUpdate({\n key,\n args\n });\n }\n\n if(updatePartClassName) {\n const chatList = this.chatList;\n const part = chatList.parentElement as HTMLElement;\n part.classList.toggle('has-contacts', !!users.length);\n }\n\n this.updateContactsLengthPromise = undefined;\n\n return users.length;\n });\n }\n\n private removeContactsPlaceholder() {\n const chatList = this.chatList;\n const parts = chatList.parentElement.parentElement;\n const bottom = chatList.parentElement.nextElementSibling as HTMLElement;\n parts.classList.remove('with-contacts');\n bottom.replaceChildren();\n this.loadContacts = undefined;\n this.processContact = undefined;\n }\n\n private _onListLengthChange = () => {\n if(!this.xd.loadedDialogsAtLeastOnce) {\n return;\n }\n\n this.checkIfPlaceholderNeeded();\n\n if(this.filterId !== FOLDER_ID_ALL) return;\n\n const chatList = this.chatList;\n const count = chatList.childElementCount;\n\n const parts = chatList.parentElement.parentElement;\n const bottom = chatList.parentElement.nextElementSibling as HTMLElement;\n const hasContacts = !!bottom.childElementCount;\n if(count >= 10) {\n if(hasContacts) {\n this.removeContactsPlaceholder();\n }\n\n return;\n } else if(hasContacts) return;\n\n parts.classList.add('with-contacts');\n\n const section = new SettingSection({\n name: 'Contacts',\n noDelimiter: true,\n fakeGradientDelimiter: true\n });\n\n section.container.classList.add('hide');\n\n this.managers.appUsersManager.getContactsPeerIds(undefined, undefined, 'online').then((contacts) => {\n let ready = false;\n const onListLengthChange = () => {\n if(ready) {\n section.container.classList.toggle('hide', !sortedUserList.list.childElementCount);\n }\n\n this.updateContactsLength(true);\n };\n\n const sortedUserList = new SortedUserList({\n avatarSize: 'abitbigger',\n createChatListOptions: {\n dialogSize: 48,\n new: true\n },\n autonomous: false,\n onListLengthChange,\n managers: this.managers\n });\n\n this.loadContacts = () => {\n const pageCount = windowSize.height / 60 | 0;\n const promise = filterAsync(contacts.splice(0, pageCount), this.verifyPeerIdForContacts);\n\n promise.then((arr) => {\n arr.forEach((peerId) => {\n sortedUserList.add(peerId);\n });\n });\n\n if(!contacts.length) {\n this.loadContacts = undefined;\n }\n };\n\n this.loadContacts();\n\n this.processContact = async(peerId) => {\n if(peerId.isAnyChat()) {\n return;\n }\n\n const good = await this.verifyPeerIdForContacts(peerId);\n const added = sortedUserList.has(peerId);\n if(!added && good) sortedUserList.add(peerId);\n else if(added && !good) sortedUserList.delete(peerId);\n };\n\n const list = sortedUserList.list;\n list.classList.add('chatlist-new');\n this.setListClickListener(list);\n section.content.append(list);\n\n ready = true;\n onListLengthChange();\n });\n\n bottom.append(section.container);\n };\n\n private verifyPeerIdForContacts = async(peerId: PeerId) => {\n const [isContact, dialog] = await Promise.all([\n this.managers.appPeersManager.isContact(peerId),\n this.managers.appMessagesManager.getDialogOnly(peerId)\n ]);\n\n return isContact && !dialog;\n };\n\n public async toggleForumTab(newTab?: ForumTab, hideTab = this.forumTab) {\n if(!hideTab && !newTab) {\n return;\n }\n\n if(hideTab) {\n const dialogElement = this.xd.getDialogElement(hideTab.peerId);\n if(dialogElement) {\n dialogElement.dom.listEl.classList.remove('is-forum-open');\n }\n }\n\n if(hideTab === newTab) {\n newTab = undefined;\n }\n\n hideTab?.toggle(false);\n const promise = newTab?.toggle(true);\n if(hideTab === this.forumTab) {\n this.forumTab = newTab;\n }\n\n if(newTab) {\n const dialogElement = this.xd.getDialogElement(newTab.peerId);\n if(dialogElement) {\n dialogElement.dom.listEl.classList.add('is-forum-open');\n }\n\n appImManager.selectTab(APP_TABS.CHATLIST);\n }\n\n if(promise) {\n await promise;\n }\n\n if(newTab && !this.forumNavigationItem) {\n this.forumNavigationItem = {\n type: 'forum',\n onPop: () => {\n this.forumNavigationItem = undefined;\n this.toggleForumTab();\n }\n };\n\n appNavigationController.pushItem(this.forumNavigationItem);\n } else if(!newTab && this.forumNavigationItem) {\n appNavigationController.removeItem(this.forumNavigationItem);\n this.forumNavigationItem = undefined;\n }\n\n const forwards = !!newTab;\n const useRafs = promise ? 2 : undefined;\n this.xd.toggleAvatarUnreadBadges(forwards, useRafs);\n\n const deferred = deferredPromise<void>();\n const duration = 300;\n SetTransition({\n element: this.forumsSlider.parentElement,\n className: 'is-forum-visible',\n duration,\n forwards,\n useRafs,\n onTransitionEnd: () => {\n deferred.resolve();\n }\n });\n\n dispatchHeavyAnimationEvent(deferred, duration).then(() => deferred.resolve());\n }\n\n public toggleForumTabByPeerId(peerId: PeerId, show?: boolean) {\n const {managers} = this;\n const history = appSidebarLeft.getHistory();\n const lastTab = history[history.length - 1];\n let forumTab: ForumTab;\n if(lastTab/* && !(lastTab instanceof AppArchivedTab) */) {\n if(lastTab instanceof ForumTab && lastTab.peerId === peerId && show) {\n shake(lastTab.container);\n return;\n }\n\n forumTab = appSidebarLeft.createTab(ForumTab);\n forumTab.open({peerId, managers});\n return;\n }\n\n forumTab = this.forumsTabs.get(peerId);\n const isSameTab = this.forumTab && this.forumTab === forumTab;\n show ??= !isSameTab;\n if(show === isSameTab) {\n if(show) {\n shake(forumTab.container);\n }\n\n return;\n }\n\n if(show && !forumTab) {\n forumTab = new ForumTab(undefined);\n forumTab.init({peerId, managers});\n\n this.forumsTabs.set(peerId, forumTab);\n this.forumsSlider.append(forumTab.container);\n\n forumTab.managers = this.managers;\n forumTab.eventListener.addEventListener('destroy', () => {\n this.forumsTabs.delete(peerId);\n });\n }\n\n return this.toggleForumTab(forumTab);\n }\n\n public setListClickListener(\n list: HTMLUListElement,\n onFound?: () => void,\n withContext = false,\n autonomous = false,\n openInner = false\n ) {\n let lastActiveListElement: HTMLElement;\n\n const setPeerFunc = (openInner ? appImManager.setInnerPeer : appImManager.setPeer).bind(appImManager);\n\n list.dataset.autonomous = '' + +autonomous;\n list.addEventListener('mousedown', (e) => {\n if(e.button !== 0) return;\n\n this.log('dialogs click list');\n const target = e.target as HTMLElement;\n const elem = findUpTag(target, DIALOG_LIST_ELEMENT_TAG);\n\n if(!elem) {\n return;\n }\n\n const peerId = elem.dataset.peerId.toPeerId();\n const lastMsgId = +elem.dataset.mid || undefined;\n const threadId = +elem.dataset.threadId || undefined;\n\n onFound?.();\n\n const isForum = !!elem.querySelector('.is-forum');\n if(isForum && !e.shiftKey && !lastMsgId) {\n this.toggleForumTabByPeerId(peerId);\n return;\n }\n\n if(e.ctrlKey || e.metaKey) {\n window.open((elem as HTMLAnchorElement).href || ('#' + peerId), '_blank');\n cancelEvent(e);\n return;\n }\n\n if(autonomous) {\n const sameElement = lastActiveListElement === elem;\n if(lastActiveListElement && !sameElement) {\n lastActiveListElement.classList.remove('active');\n }\n\n if(elem) {\n elem.classList.add('active');\n lastActiveListElement = elem;\n this.lastActiveElements.add(elem);\n }\n }\n\n if(\n (!threadId || lastMsgId) &&\n this.xd.sortedList.list === list &&\n this.xd !== this.xds[FOLDER_ID_ARCHIVE]\n ) {\n this.toggleForumTab();\n }\n\n setPeerFunc({\n peerId,\n lastMsgId,\n threadId: threadId\n });\n }, {capture: true});\n\n // cancel link click\n // ! do not change it to attachClickEvent\n list.addEventListener('click', (e) => {\n if(e.button === 0) {\n cancelEvent(e);\n }\n }, {capture: true});\n\n if(withContext) {\n this.contextMenu.attach(list);\n }\n }\n\n public createChatList(options: {\n // avatarSize?: number,\n // handheldsSize?: number,\n // size?: number,\n new?: boolean,\n dialogSize?: number,\n ignoreClick?: boolean\n } = {}) {\n const list = document.createElement('ul');\n list.classList.add('chatlist'/* ,\n 'chatlist-avatar-' + (options.avatarSize || 54) *//* , 'chatlist-' + (options.size || 72) */);\n\n if(options.new) {\n list.classList.add('chatlist-new');\n }\n\n if(options.dialogSize) {\n list.classList.add('chatlist-' + options.dialogSize);\n }\n\n // if(options.ignoreClick) {\n // list.classList.add('disable-hover');\n // }\n\n /* if(options.handheldsSize) {\n list.classList.add('chatlist-handhelds-' + options.handheldsSize);\n } */\n\n return list;\n }\n\n public setLastMessageN(options: Parameters<AppDialogsManager['setLastMessage']>[0]) {\n const promise = this.setLastMessage(options);\n return promise.catch((err: ApiError) => {\n if(err?.type !== 'MIDDLEWARE') {\n this.log.error('set last message error', err);\n }\n });\n }\n\n private async setLastMessage({\n dialog,\n lastMessage,\n dialogElement,\n highlightWord,\n isBatch = false,\n setUnread = false\n }: {\n dialog: Dialog | ForumTopic,\n lastMessage?: Message.message | Message.messageService,\n dialogElement?: DialogElement,\n highlightWord?: string,\n isBatch?: boolean,\n setUnread?: boolean\n }) {\n if(!dialogElement) {\n dialogElement = this.xd.getDialogElement(dialog.peerId);\n\n if(!dialogElement) {\n return;\n }\n }\n\n const {dom} = dialogElement;\n const {peerId} = dialog;\n\n const {deferred: promise, middleware} = setPromiseMiddleware(dom, 'setLastMessagePromise');\n\n let draftMessage: MyDraftMessage;\n if(!lastMessage) {\n if(\n dialog.draft?._ === 'draftMessage' && (\n !peerId.isAnyChat() ||\n dialog._ === 'forumTopic' ||\n !(await this.managers.appPeersManager.isForum(peerId))\n )\n ) {\n draftMessage = dialog.draft;\n }\n\n lastMessage = (dialog as Dialog).topMessage;\n if(lastMessage?.mid !== dialog.top_message) {\n const promise = this.managers.appMessagesManager.getMessageByPeer(peerId, dialog.top_message);\n lastMessage = await middleware(promise);\n }\n }\n\n const isSearch = setUnread !== null && !setUnread;\n // * do not uncomment `setUnread` - unsetTyping right after this call will interrupt setting unread badges\n if(/* setUnread */!isSearch) {\n this.setUnreadMessagesN({dialog, dialogElement, isBatch, setLastMessagePromise: promise});\n }\n\n if(!lastMessage/* || (lastMessage._ === 'messageService' && !lastMessage.rReply) */) {\n dom.lastMessageSpan.replaceChildren();\n dom.lastTimeSpan.replaceChildren();\n delete dom.listEl.dataset.mid;\n\n promise.resolve();\n return;\n }\n\n const isRestricted = lastMessage && isMessageRestricted(lastMessage as Message.message);\n\n /* if(!dom.lastMessageSpan.classList.contains('user-typing')) */ {\n let mediaContainer: HTMLElement;\n const willPrepend: (Promise<any> | HTMLElement)[] = [];\n if(lastMessage && !draftMessage && !isRestricted) {\n const media = getMediaFromMessage(lastMessage, true);\n const videoTypes: Set<MyDocument['type']> = new Set(['video', 'gif', 'round']);\n if(media && (media._ === 'photo' || videoTypes.has(media.type))) {\n const size = choosePhotoSize(media, 20, 20);\n\n if(size._ !== 'photoSizeEmpty') {\n mediaContainer = document.createElement('div');\n mediaContainer.classList.add('dialog-subtitle-media');\n\n if((media as MyDocument).type === 'round') {\n mediaContainer.classList.add('is-round');\n }\n\n willPrepend.push(wrapPhoto({\n photo: media,\n message: lastMessage,\n container: mediaContainer,\n withoutPreloader: true,\n size\n }).then(() => mediaContainer));\n\n if(videoTypes.has((media as MyDocument).type)) {\n const playIcon = document.createElement('span');\n playIcon.classList.add('tgico-play');\n\n mediaContainer.append(playIcon);\n }\n }\n }\n }\n\n /* if(lastMessage.from_id === auth.id) { // You: */\n if(draftMessage) {\n const span = document.createElement('span');\n span.classList.add('danger');\n span.append(i18n('Draft'), ': ');\n willPrepend.unshift(span);\n } else if(peerId.isAnyChat() && peerId !== lastMessage.fromId && !(lastMessage as Message.messageService).action) {\n const span = document.createElement('span');\n span.classList.add('primary-text');\n\n if(lastMessage.fromId === rootScope.myId) {\n span.append(i18n('FromYou'));\n willPrepend.unshift(span);\n } else {\n // str = sender.first_name || sender.last_name || sender.username;\n const p = middleware(wrapPeerTitle({\n peerId: lastMessage.fromId,\n onlyFirstName: true\n })).then((element) => {\n span.prepend(element);\n return span;\n }, noop);\n\n willPrepend.unshift(p);\n }\n\n span.append(': ');\n // console.log(sender, senderBold.innerText);\n }\n\n const withoutMediaType = !!mediaContainer && !!(lastMessage as Message.message)?.message;\n\n let fragment: DocumentFragment;\n if(highlightWord && (lastMessage as Message.message).message) {\n fragment = await middleware(wrapMessageForReply({message: lastMessage, highlightWord, withoutMediaType}));\n } else if(draftMessage) {\n fragment = await middleware(wrapMessageForReply({message: draftMessage}));\n } else if(lastMessage) {\n fragment = await middleware(wrapMessageForReply({message: lastMessage, withoutMediaType}));\n } else { // rare case\n fragment = document.createDocumentFragment();\n }\n\n if(willPrepend.length) {\n const elements = await middleware(Promise.all(willPrepend));\n fragment.prepend(...elements);\n }\n\n replaceContent(dom.lastMessageSpan, fragment);\n }\n\n if(lastMessage || draftMessage/* && lastMessage._ !== 'draftMessage' */) {\n const date = draftMessage ? Math.max(draftMessage.date, lastMessage.date || 0) : lastMessage.date;\n replaceContent(dom.lastTimeSpan, formatDateAccordingToTodayNew(new Date(date * 1000)));\n } else dom.lastTimeSpan.textContent = '';\n\n if(isSearch) {\n dom.listEl.dataset.mid = '' + lastMessage.mid;\n\n const replyTo = lastMessage.reply_to;\n if(replyTo?.pFlags?.forum_topic) {\n dom.listEl.dataset.threadId = '' + getMessageThreadId(lastMessage);\n }\n }\n\n promise.resolve();\n }\n\n public setUnreadMessagesN(options: Parameters<AppDialogsManager['setUnreadMessages']>[0]) {\n return this.setUnreadMessages(options).catch(() => {});\n }\n\n private async setUnreadMessages({\n dialog,\n dialogElement,\n isBatch = false,\n setLastMessagePromise\n }: {\n dialog: Dialog | ForumTopic,\n dialogElement: DialogElement,\n isBatch?: boolean,\n setLastMessagePromise?: Promise<void>\n }) {\n const {dom} = dialogElement;\n if(!dom) {\n // this.log.error('setUnreadMessages no dom!', dialog);\n return;\n }\n\n const isTopic = dialog._ === 'forumTopic';\n\n const {deferred, middleware} = setPromiseMiddleware(dom, 'setUnreadMessagePromise');\n\n const {peerId} = dialog;\n const promises = Promise.all([\n this.managers.appNotificationsManager.isPeerLocalMuted({peerId: peerId, respectType: true, threadId: isTopic ? dialog.id : undefined}),\n dialog.draft?._ !== 'draftMessage' ? this.managers.appMessagesManager.getMessageByPeer(peerId, dialog.top_message) : undefined,\n isTopic ? !!dialog.pFlags.pinned : this.managers.dialogsStorage.isDialogPinned(peerId, this.filterId),\n this.managers.appMessagesManager.isDialogUnread(dialog),\n peerId.isAnyChat() && !isTopic ? this.managers.acknowledged.dialogsStorage.getForumUnreadCount(peerId).then((result) => {\n if(result.cached) {\n return result.result;\n } else {\n result.result.then(() => {\n this.setUnreadMessagesN({dialog, dialogElement});\n });\n\n return {count: 0, hasUnmuted: false};\n }\n }).catch(() => undefined as {count: number, hasUnmuted: boolean}) : undefined\n ]);\n\n let [isMuted, lastMessage, isPinned, isDialogUnread, forumUnreadCount] = await middleware(promises);\n const wasMuted = dom.listEl.classList.contains('is-muted');\n\n const {count: unreadTopicsCount, hasUnmuted: hasUnmutedTopic} = forumUnreadCount || {};\n\n let setStatusMessage: MyMessage;\n if(lastMessage && lastMessage.pFlags.out && lastMessage.peerId !== rootScope.myId) {\n setStatusMessage = lastMessage;\n }\n\n const unreadCount = unreadTopicsCount ?? dialog.unread_count;\n if(unreadTopicsCount !== undefined) {\n isDialogUnread = !!unreadCount;\n }\n\n if(isTopic && !isDialogUnread) {\n isDialogUnread = !getServerMessageId(dialog.read_inbox_max_id);\n }\n\n const hasUnreadBadge = isPinned || isDialogUnread;\n const hasUnreadAvatarBadge = this.xd !== this.xds[FOLDER_ID_ARCHIVE] && !isTopic && !!this.forumTab && this.xd.getDialogElement(peerId) === dialogElement && isDialogUnread;\n // dom.messageEl.classList.toggle('has-badge', hasBadge);\n\n // * have to await all promises before modifying something\n\n if(setLastMessagePromise) {\n try {\n await middleware(setLastMessagePromise);\n } catch(err) {\n return;\n }\n }\n\n const transitionDuration = isBatch ? 0 : BADGE_TRANSITION_TIME;\n\n dom.listEl.classList.toggle('no-unmuted-topic', !isMuted && hasUnmutedTopic !== undefined && !hasUnmutedTopic);\n\n if(isMuted !== wasMuted) {\n SetTransition({\n element: dom.listEl,\n className: 'is-muted',\n forwards: isMuted,\n duration: transitionDuration\n });\n }\n\n setSendingStatus(dom.statusSpan, isTopic && dialog.pFlags.closed ? 'premium_lock' : setStatusMessage, true);\n\n // if(isTopic) {\n // dom.statusSpan.parentElement.classList.toggle('is-closed', !!dialog.pFlags.closed);\n // }\n\n const isUnreadBadgeMounted = !!dom.unreadBadge;\n if(hasUnreadBadge) {\n dialogElement.createUnreadBadge();\n }\n\n const isUnreadAvatarBadgeMounted = !!dom.unreadAvatarBadge;\n if(hasUnreadAvatarBadge) {\n dialogElement.createUnreadAvatarBadge();\n }\n\n const hasMentionsBadge = dialog.unread_mentions_count && (dialog.unread_mentions_count > 1 || dialog.unread_count > 1);\n const isMentionsBadgeMounted = !!dom.mentionsBadge;\n if(hasMentionsBadge) {\n dialogElement.createMentionsBadge();\n }\n\n const a: [Parameters<DialogElement['toggleBadgeByKey']>[0], boolean, boolean][] = [\n ['unreadBadge', hasUnreadBadge, isUnreadBadgeMounted],\n ['unreadAvatarBadge', hasUnreadAvatarBadge, isUnreadAvatarBadgeMounted],\n ['mentionsBadge', hasMentionsBadge, isMentionsBadgeMounted]\n ];\n\n a.forEach(([key, hasBadge, isBadgeMounted]) => {\n const badge = dom[key];\n if(!badge) {\n return;\n }\n\n dialogElement.toggleBadgeByKey(key, hasBadge, isBadgeMounted, isBatch);\n });\n\n if(!hasUnreadBadge) {\n deferred.resolve();\n return;\n }\n\n if(isPinned) {\n dom.unreadBadge.classList.add('tgico-chatspinned', 'tgico');\n } else if(dom.unreadBadge) {\n dom.unreadBadge.classList.remove('tgico-chatspinned', 'tgico');\n }\n\n let isUnread = true, isMention = false, unreadBadgeText: string;\n if(dialog.unread_mentions_count && unreadCount === 1) {\n unreadBadgeText = '@';\n isMention = true;\n // dom.unreadBadge.classList.add('tgico-mention', 'tgico');\n } else if(isDialogUnread) {\n // dom.unreadMessagesSpan.innerText = '' + (unreadCount ? formatNumber(unreadCount, 1) : ' ');\n unreadBadgeText = '' + (unreadCount ? formatNumber(unreadCount, 1) : ' ');\n } else {\n unreadBadgeText = '';\n isUnread = false;\n }\n\n if(isTopic) {\n const notVisited = isDialogUnread && unreadBadgeText === ' ';\n dom.unreadBadge.classList.toggle('not-visited', notVisited);\n }\n\n const b: Array<[HTMLElement, string]> = [\n [dom.unreadBadge, unreadBadgeText],\n [dom.unreadAvatarBadge, unreadBadgeText || undefined]\n ];\n\n b.filter(Boolean).forEach(([badge, text]) => {\n if(text !== undefined) {\n badge.innerText = unreadBadgeText;\n }\n\n badge.classList.toggle('unread', isUnread);\n badge.classList.toggle('mention', isMention);\n });\n\n deferred.resolve();\n }\n\n private async getDialog(dialog: Dialog | ForumTopic | PeerId, threadId?: number) {\n if(typeof(dialog) !== 'object') {\n let originalDialog: Dialog | ForumTopic;\n if(threadId) {\n originalDialog = await this.managers.dialogsStorage.getForumTopic(dialog, threadId);\n if(!originalDialog) {\n const peerId = dialog || NULL_PEER_ID;\n return {\n peerId,\n pFlags: {}\n } as any as ForumTopic;\n }\n } else {\n originalDialog = await this.managers.appMessagesManager.getDialogOnly(dialog);\n if(!originalDialog) {\n const peerId = dialog || NULL_PEER_ID;\n return {\n peerId,\n peer: await this.managers.appPeersManager.getOutputPeer(peerId),\n pFlags: {}\n } as any as Dialog;\n }\n }\n\n return originalDialog;\n }\n\n return dialog as Dialog | ForumTopic;\n }\n\n public addListDialog(options: Parameters<AppDialogsManager['addDialogNew']>[0] & {isBatch?: boolean}) {\n options.autonomous = false;\n\n const ret = this.addDialogNew(options);\n\n if(ret) {\n const {peerId} = options;\n const getDialogPromise = this.getDialog(peerId, options.threadId);\n const promise = getDialogPromise.then((dialog) => {\n const promises: Promise<any>[] = [];\n const isUser = peerId.isUser();\n if(!isUser && dialog._ === 'dialog') {\n promises.push(this.xd.processDialogForCallStatus(peerId, ret.dom));\n }\n\n if(peerId !== rootScope.myId && isUser) {\n promises.push(this.managers.appUsersManager.getUserStatus(peerId.toUserId()).then((status) => {\n if(status?._ === 'userStatusOnline') {\n this.xd.setOnlineStatus(ret.dom.avatarEl, true);\n }\n }));\n }\n\n promises.push(this.setLastMessageN({\n dialog,\n dialogElement: ret,\n isBatch: options.isBatch,\n setUnread: true\n }));\n\n return Promise.all(promises);\n });\n\n options.loadPromises?.push(promise);\n }\n\n return ret;\n }\n\n /**\n * use for rendering search result\n */\n public addDialogAndSetLastMessage(options: Omit<Parameters<AppDialogsManager['addDialogNew']>[0], 'dialog'> & {\n message: MyMessage,\n peerId: PeerId,\n query?: string\n }) {\n const {peerId, message, query} = options;\n const ret = this.addDialogNew({\n ...options,\n ...getMessageSenderPeerIdOrName(message),\n peerId\n });\n\n this.setLastMessageN({\n dialog: {_: 'dialog', peerId} as any,\n lastMessage: message,\n dialogElement: ret,\n highlightWord: query\n });\n\n if(message.peerId !== peerId) {\n ret.dom.listEl.dataset.peerId = '' + message.peerId;\n }\n\n return ret;\n }\n\n public addDialogNew(options: DialogElementOptions & {container?: HTMLElement | Scrollable | false, append?: boolean}) {\n const d = new DialogElement({\n autonomous: !!options.container,\n avatarSize: 'bigger',\n ...options\n // avatarSize: !options.avatarSize || options.avatarSize >= 54 ? 'bigger' : 'abitbigger',\n });\n\n if(options.container) {\n const method = !options.append ? 'append' : 'prepend';\n options.container[method](d.container);\n }\n\n return d;\n // return this.addDialog(options.peerId, options.container, options.rippleEnabled, options.onlyFirstName, options.meAsSaved, options.append, options.avatarSize, options.autonomous, options.lazyLoadQueue, options.loadPromises, options.fromName, options.noIcons);\n }\n}\n\nconst appDialogsManager = new AppDialogsManager();\nMOUNT_CLASS_TO.appDialogsManager = appDialogsManager;\nexport default appDialogsManager;\n","export default function getUnsafeRandomInt(min: number, max: number) {\n min = Math.ceil(min);\n max = Math.floor(max);\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {DownloadMediaOptions, DownloadOptions} from '../mtproto/apiFileManager';\nimport type {AppMessagesManager} from './appMessagesManager';\nimport type {MyDocument} from './appDocsManager';\nimport deferredPromise, {CancellablePromise} from '../../helpers/cancellablePromise';\nimport {InputFile, Photo, PhotoSize} from '../../layer';\nimport getFileNameForUpload from '../../helpers/getFileNameForUpload';\nimport {AppManagers} from './managers';\nimport rootScope from '../rootScope';\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport noop from '../../helpers/noop';\nimport getDownloadMediaDetails from './utils/download/getDownloadMediaDetails';\nimport getDownloadFileNameFromOptions from './utils/download/getDownloadFileNameFromOptions';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport makeError from '../../helpers/makeError';\nimport createDownloadAnchor from '../../helpers/dom/createDownloadAnchor';\nimport {getFileNameByLocation} from '../../helpers/fileName';\nimport getDocumentDownloadOptions from './utils/docs/getDocumentDownloadOptions';\nimport getPhotoDownloadOptions from './utils/photos/getPhotoDownloadOptions';\nimport apiManagerProxy from '../mtproto/mtprotoworker';\n\nexport type ResponseMethodBlob = 'blob';\nexport type ResponseMethodJson = 'json';\nexport type ResponseMethod = ResponseMethodBlob | ResponseMethodJson;\n\n/* export type DownloadBlob = {promise: Promise<Blob>, controller: AbortController};\nexport type DownloadJson = {promise: Promise<any>, controller: AbortController}; */\nexport type DownloadBlob = CancellablePromise<Blob>;\nexport type DownloadUrl = CancellablePromise<string>;\nexport type DownloadJson = CancellablePromise<any>;\n// export type Download = DownloadBlob/* | DownloadJson */;\nexport type Download = DownloadBlob | DownloadUrl/* | DownloadJson */;\n\nexport type Progress = {done: number, fileName: string, total: number, offset: number};\nexport type ProgressCallback = (details: Progress) => void;\n\ntype DownloadType = 'url' | 'blob' | 'void' | 'disc';\n\nexport class AppDownloadManager {\n private downloads: {[fileName: string]: {main: Download} & {[type in DownloadType]?: Download}} = {};\n // private downloadsToDisc: {[fileName: string]: Download} = {};\n private progress: {[fileName: string]: Progress} = {};\n // private progressCallbacks: {[fileName: string]: Array<ProgressCallback>} = {};\n private managers: AppManagers;\n\n public construct(managers: AppManagers) {\n this.managers = managers;\n rootScope.addEventListener('download_progress', (details) => {\n // const callbacks = this.progressCallbacks[details.fileName];\n // if(callbacks) {\n // callbacks.forEach((callback) => callback(details));\n // }\n\n const download = this.downloads[details.fileName];\n if(download?.main?.notifyAll) {\n this.progress[details.fileName] = details;\n download.main.notifyAll(details);\n }\n });\n }\n\n private getNewDeferred<T>(fileName: string, type?: DownloadType) {\n const deferred = deferredPromise<T>();\n\n let download = this.downloads[fileName];\n if(!download) {\n download = this.downloads[fileName] = {\n main: deferred as any\n };\n\n deferred.cancel = () => {\n const error = makeError('DOWNLOAD_CANCELED');\n\n this.managers.apiFileManager.cancelDownload(fileName);\n\n deferred.reject(error);\n deferred.cancel = noop;\n };\n\n deferred.catch(() => {\n this.clearDownload(fileName, type);\n }).finally(() => {\n delete this.progress[fileName];\n // delete this.progressCallbacks[fileName];\n });\n } else {\n const main = download.main;\n (['cancel', 'addNotifyListener', 'notify', 'notifyAll'] as (keyof CancellablePromise<void>)[]).forEach((key) => {\n if(!main[key]) {\n return;\n }\n\n // @ts-ignore\n deferred[key] = main[key].bind(main);\n });\n }\n\n const haveToClear = type === 'disc';\n if(haveToClear) {\n deferred.catch(noop).finally(() => {\n this.clearDownload(fileName, type);\n });\n }\n\n return download[type] = deferred as any;\n }\n\n public getNewDeferredForUpload<T extends Promise<any>>(fileName: string, promise: T) {\n const deferred = this.getNewDeferred<InputFile>(fileName);\n promise.then(deferred.resolve, deferred.reject);\n\n deferred.finally(() => {\n this.clearDownload(fileName);\n });\n\n return deferred as CancellablePromise<Awaited<T>>;\n }\n\n private clearDownload(fileName: string, type?: DownloadType) {\n const downloads = this.downloads[fileName];\n if(!downloads) {\n return;\n }\n\n delete downloads[type];\n\n const length = Object.keys(downloads).length;\n if(!length || (downloads.main && length === 1)) {\n delete this.downloads[fileName];\n }\n }\n\n public getUpload(fileName: string): ReturnType<AppMessagesManager['sendFile']>['promise'] {\n let deferred: CancellablePromise<any> = this.getDownload(fileName);\n if(deferred) {\n return deferred;\n }\n\n deferred = this.getNewDeferred(fileName);\n this.managers.appMessagesManager.getUploadPromise(fileName).then(deferred.resolve, deferred.reject);\n return deferred;\n }\n\n /* public fakeDownload(fileName: string, value: Blob | string) {\n const deferred = this.getNewDeferred<Blob>(fileName);\n if(typeof(value) === 'string') {\n fetch(value)\n .then((response) => response.blob())\n .then((blob) => deferred.resolve(blob));\n } else {\n deferred.resolve(value);\n }\n\n return deferred;\n } */\n\n private d(fileName: string, getPromise: () => Promise<any>, type?: DownloadType) {\n let deferred = this.getDownload(fileName, type);\n if(deferred) return deferred;\n\n deferred = this.getNewDeferred<Blob>(fileName, type);\n getPromise().then(deferred.resolve, deferred.reject);\n return deferred;\n }\n\n public download(options: DownloadOptions): DownloadBlob {\n const fileName = getDownloadFileNameFromOptions(options);\n return this.d(fileName, () => this.managers.apiFileManager.download(options), 'blob') as any;\n }\n\n public downloadMedia(options: DownloadMediaOptions, type: DownloadType = 'blob', promiseBefore?: Promise<any>): DownloadBlob {\n const {downloadOptions, fileName} = getDownloadMediaDetails(options);\n\n return this.d(fileName, () => {\n let cb: any;\n if(type === 'url') {\n cb = this.managers.apiFileManager.downloadMediaURL;\n } else if(type === 'void'/* || type === 'disc' */) {\n cb = this.managers.apiFileManager.downloadMediaVoid;\n } else /* if(type === 'blob') */ {\n cb = this.managers.apiFileManager.downloadMedia;\n }\n\n if(promiseBefore) {\n return promiseBefore.then(() => cb(options));\n }\n\n return cb(options);\n }, type) as any;\n }\n\n public downloadMediaURL(options: DownloadMediaOptions): DownloadUrl {\n return this.downloadMedia(options, 'url') as any;\n }\n\n public downloadMediaVoid(options: DownloadMediaOptions): DownloadBlob {\n return this.downloadMedia(options, 'void');\n }\n\n public upload(file: File | Blob, fileName?: string, promise?: Promise<any>) {\n if(!fileName) {\n fileName = getFileNameForUpload(file);\n }\n\n if(!promise) {\n promise = this.managers.apiFileManager.upload({file, fileName});\n }\n\n const deferred = this.getNewDeferredForUpload(fileName, promise);\n return deferred as any as CancellablePromise<InputFile>;\n }\n\n public getDownload(fileName: string, type?: DownloadType) {\n const d = this.downloads[fileName];\n return d && d[type];\n }\n\n // public addProgressCallback(fileName: string, callback: ProgressCallback) {\n // const progress = this.progress[fileName];\n // (this.progressCallbacks[fileName] ?? (this.progressCallbacks[fileName] = [])).push(callback);\n\n // if(progress) {\n // callback(progress);\n // }\n // }\n\n public downloadToDisc(options: DownloadMediaOptions, justAttach?: boolean) {\n const media = options.media;\n const isDocument = media._ === 'document';\n if(!isDocument && !options.thumb) {\n options.thumb = (media as Photo.photo).sizes.slice().pop() as PhotoSize.photoSize;\n }\n\n // const {fileName: cacheFileName} = getDownloadMediaDetails(options);\n // if(justAttach) {\n // const promise = this.downloadsToDisc[cacheFileName];\n // if(promise) {\n // return promise;\n // }\n // }\n\n // const {downloadOptions, fileName} = getDownloadMediaDetails(options);\n // if(downloadOptions.size && downloadOptions.size > MAX_FILE_SAVE_SIZE) {\n const id = '' + (Math.random() * 0x7FFFFFFF | 0);\n // const id = 'test';\n const url = `download/${id}`;\n options.downloadId = id;\n\n const pingPromise = apiManagerProxy.pingServiceWorkerWithIframe();\n\n const promise = this.downloadMedia(options, 'disc', pingPromise);\n // this.downloadsToDisc[cacheFileName] = promise;\n\n if(justAttach) {\n return promise;\n }\n\n const iframe = document.createElement('iframe');\n iframe.hidden = true;\n\n pingPromise.then(() => {\n iframe.src = url;\n document.body.append(iframe);\n });\n\n // createDownloadAnchor(url, 'asd.txt');\n\n // const events = [\n // 'emptied',\n // 'abort',\n // 'suspend',\n // 'reset',\n // 'error',\n // 'ended',\n // 'load'\n // ].forEach((event) => {\n // iframe.addEventListener(event, () => alert(event));\n // iframe.contentWindow.addEventListener(event, () => alert(event));\n // });\n\n let element: HTMLElement, hadProgress = false;\n const onProgress = () => {\n if(hadProgress) {\n return;\n }\n\n hadProgress = true;\n element = iframe;\n\n indexOfAndSplice(promise.listeners, onProgress);\n };\n\n promise.addNotifyListener(onProgress);\n promise.then((blob) => {\n if(!blob) {\n return;\n }\n\n const url = URL.createObjectURL(blob);\n const downloadOptions = isDocument ?\n getDocumentDownloadOptions(media) :\n getPhotoDownloadOptions(media as any, options.thumb as PhotoSize.photoSize);\n const fileName = (options.media as MyDocument).file_name || getFileNameByLocation(downloadOptions.location);\n createDownloadAnchor(url, downloadOptions.fileName || fileName, () => {\n URL.revokeObjectURL(url);\n });\n }).catch(noop).finally(() => {\n if(!hadProgress) {\n onProgress();\n }\n\n setTimeout(() => {\n element?.remove();\n }, 1000);\n\n // if(this.downloadsToDisc[cacheFileName] === promise) {\n // delete this.downloadsToDisc[cacheFileName];\n // }\n });\n\n return promise;\n }\n}\n\nconst appDownloadManager = new AppDownloadManager();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.appDownloadManager = appDownloadManager);\nexport default appDownloadManager;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function createDownloadAnchor(url: string, fileName: string, onRemove?: () => void) {\n const a = document.createElement('a');\n a.href = url;\n a.download = fileName;\n a.target = '_blank';\n\n a.style.position = 'absolute';\n a.style.top = '1px';\n a.style.left = '1px';\n\n document.body.append(a);\n\n try {\n const clickEvent = document.createEvent('MouseEvents');\n clickEvent.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n a.dispatchEvent(clickEvent);\n } catch(e) {\n console.error('Download click error', e);\n try {\n a.click();\n } catch(e) {\n window.open(url as string, '_blank');\n }\n }\n\n setTimeout(() => {\n a.remove();\n onRemove && onRemove();\n }, 100);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type Chat from './chat';\nimport type ChatTopbar from './topbar';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport DivAndCaption from '../divAndCaption';\nimport ripple from '../ripple';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport {Message} from '../../layer';\nimport safeAssign from '../../helpers/object/safeAssign';\n\nconst classNames: string[] = ['is-pinned-message-shown', 'is-pinned-audio-shown'];\nconst CLASSNAME_BASE = 'pinned-container';\nconst HEIGHT = 52;\n\nexport default class PinnedContainer {\n public wrapperUtils: HTMLElement;\n public btnClose: HTMLElement;\n protected wrapper: HTMLElement;\n\n protected topbar: ChatTopbar;\n protected chat: Chat;\n protected listenerSetter: ListenerSetter;\n public className: string;\n public divAndCaption: DivAndCaption<(title: string | HTMLElement | DocumentFragment, subtitle: string | HTMLElement | DocumentFragment, message?: any) => void>;\n\n protected floating = false;\n\n public onClose?: () => void | Promise<boolean>;\n\n constructor(options: {\n topbar: PinnedContainer['topbar'],\n chat: PinnedContainer['chat'],\n listenerSetter: PinnedContainer['listenerSetter'],\n className: PinnedContainer['className'],\n divAndCaption: PinnedContainer['divAndCaption'],\n onClose?: PinnedContainer['onClose'],\n floating?: PinnedContainer['floating']\n }) {\n safeAssign(this, options);\n\n const {divAndCaption, className} = this;\n divAndCaption.container.classList.add(CLASSNAME_BASE, 'hide');\n divAndCaption.title.classList.add(CLASSNAME_BASE + '-title');\n divAndCaption.subtitle.classList.add(CLASSNAME_BASE + '-subtitle');\n divAndCaption.content.classList.add(CLASSNAME_BASE + '-content');\n\n this.btnClose = document.createElement('button');\n this.btnClose.classList.add(CLASSNAME_BASE + '-close', `pinned-${className}-close`, 'btn-icon', 'tgico-close');\n\n this.wrapper = document.createElement('div');\n this.wrapper.classList.add(CLASSNAME_BASE + '-wrapper');\n ripple(this.wrapper);\n\n this.wrapperUtils = document.createElement('div');\n this.wrapperUtils.classList.add(CLASSNAME_BASE + '-wrapper-utils');\n this.wrapperUtils.append(this.btnClose);\n\n this.wrapper.append(...Array.from(divAndCaption.container.children), this.wrapperUtils);\n\n divAndCaption.container.append(this.wrapper/* , this.close */);\n\n this.attachOnCloseEvent(this.btnClose);\n }\n\n public attachOnCloseEvent(elem: HTMLElement) {\n attachClickEvent(elem, (e) => {\n cancelEvent(e);\n\n ((this.onClose ? this.onClose() : null) || Promise.resolve(true)).then((needClose) => {\n if(needClose) {\n this.toggle(true);\n }\n });\n }, {listenerSetter: this.listenerSetter});\n }\n\n public toggle(hide?: boolean) {\n const isHidden = this.divAndCaption.container.classList.contains('hide');\n if(hide === undefined) {\n hide = !isHidden;\n } else if(hide === isHidden) {\n return;\n }\n\n // const scrollable = this.chat.bubbles.scrollable;\n\n const isFloating = (this.floating || mediaSizes.isMobile) && !hide;\n // const scrollTop = isFloating || this.divAndCaption.container.classList.contains('is-floating') ? scrollable.scrollTop : undefined;\n\n this.divAndCaption.container.classList.toggle('is-floating', isFloating);\n this.divAndCaption.container.classList.toggle('hide', hide);\n\n this.topbar.container.classList.toggle('is-pinned-floating', isFloating);\n this.topbar.container.classList.toggle(`is-pinned-${this.className}-shown`, !hide);\n\n // const active = classNames.filter((className) => this.topbar.container.classList.contains(className));\n // const maxActive = hide ? 0 : 1;\n\n // * not sure when it became unneeded\n // if(scrollTop !== undefined && active.length <= maxActive/* && !scrollable.isScrolledDown */) {\n // scrollable.scrollTop = scrollTop + ((hide ? -1 : 1) * HEIGHT);\n // }\n\n this.topbar.setFloating();\n this.topbar.setUtilsWidth();\n }\n\n public isVisible() {\n return !this.divAndCaption.container.classList.contains('hide');\n }\n\n public isFloating() {\n return this.divAndCaption.container.classList.contains('is-floating');\n }\n\n public fill(title: string | HTMLElement | DocumentFragment, subtitle: string | HTMLElement | DocumentFragment, message: Message.message) {\n this.divAndCaption.container.dataset.peerId = '' + message.peerId;\n this.divAndCaption.container.dataset.mid = '' + message.mid;\n this.divAndCaption.fill(title, subtitle, message);\n this.topbar.setUtilsWidth();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {AppMessagesManager} from '../../lib/appManagers/appMessagesManager';\nimport type ChatTopbar from './topbar';\nimport rootScope from '../../lib/rootScope';\nimport appMediaPlaybackController, {AppMediaPlaybackController} from '../appMediaPlaybackController';\nimport DivAndCaption from '../divAndCaption';\nimport PinnedContainer from './pinnedContainer';\nimport Chat from './chat';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport PeerTitle from '../peerTitle';\nimport {i18n} from '../../lib/langPack';\nimport {formatFullSentTime} from '../../helpers/date';\nimport ButtonIcon from '../buttonIcon';\nimport {DocumentAttribute} from '../../layer';\nimport MediaProgressLine from '../mediaProgressLine';\nimport VolumeSelector from '../volumeSelector';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport {AppManagers} from '../../lib/appManagers/managers';\n\nexport default class ChatAudio extends PinnedContainer {\n private toggleEl: HTMLElement;\n private progressLine: MediaProgressLine;\n private volumeSelector: VolumeSelector;\n private fasterEl: HTMLElement;\n private repeatEl: HTMLButtonElement;\n\n constructor(protected topbar: ChatTopbar, protected chat: Chat, protected managers: AppManagers) {\n super({\n topbar,\n chat,\n listenerSetter: topbar.listenerSetter,\n className: 'audio',\n divAndCaption: new DivAndCaption(\n 'pinned-audio',\n (title: string | HTMLElement | DocumentFragment, subtitle: string | HTMLElement | DocumentFragment) => {\n replaceContent(this.divAndCaption.title, title);\n replaceContent(this.divAndCaption.subtitle, subtitle);\n }\n ),\n onClose: () => {\n appMediaPlaybackController.stop(undefined, true);\n },\n floating: true\n });\n\n this.divAndCaption.border.remove();\n\n const prevEl = ButtonIcon('fast_rewind active', {noRipple: true});\n const nextEl = ButtonIcon('fast_forward active', {noRipple: true});\n\n const attachClick = (elem: HTMLElement, callback: () => void) => {\n attachClickEvent(elem, (e) => {\n cancelEvent(e);\n callback();\n }, {listenerSetter: this.topbar.listenerSetter});\n };\n\n attachClick(prevEl, () => {\n appMediaPlaybackController.previous();\n });\n\n attachClick(nextEl, () => {\n appMediaPlaybackController.next();\n });\n\n this.toggleEl = ButtonIcon('', {noRipple: true});\n this.toggleEl.classList.add('active', 'pinned-audio-ico', 'tgico');\n attachClick(this.toggleEl, () => {\n appMediaPlaybackController.toggle();\n });\n this.wrapper.prepend(this.wrapper.firstElementChild, prevEl, this.toggleEl, nextEl);\n\n this.volumeSelector = new VolumeSelector(this.listenerSetter, true);\n const volumeProgressLineContainer = document.createElement('div');\n volumeProgressLineContainer.classList.add('progress-line-container');\n volumeProgressLineContainer.append(this.volumeSelector.container);\n const tunnel = document.createElement('div');\n tunnel.classList.add('pinned-audio-volume-tunnel');\n this.volumeSelector.btn.classList.add('pinned-audio-volume', 'active');\n this.volumeSelector.btn.prepend(tunnel);\n this.volumeSelector.btn.append(volumeProgressLineContainer);\n\n this.repeatEl = ButtonIcon('audio_repeat', {noRipple: true});\n attachClick(this.repeatEl, () => {\n const params = appMediaPlaybackController.getPlaybackParams();\n if(!params.round) {\n appMediaPlaybackController.round = true;\n } else if(params.loop) {\n appMediaPlaybackController.round = false;\n appMediaPlaybackController.loop = false;\n } else {\n appMediaPlaybackController.loop = !appMediaPlaybackController.loop;\n }\n });\n\n const fasterEl = this.fasterEl = ButtonIcon('playback_2x', {noRipple: true});\n attachClick(fasterEl, () => {\n appMediaPlaybackController.playbackRate = fasterEl.classList.contains('active') ? 1 : 1.75;\n });\n\n this.wrapperUtils.prepend(this.volumeSelector.btn, fasterEl, this.repeatEl);\n\n const progressWrapper = document.createElement('div');\n progressWrapper.classList.add('pinned-audio-progress-wrapper');\n\n this.progressLine = new MediaProgressLine({\n withTransition: true,\n useTransform: true\n });\n this.progressLine.container.classList.add('pinned-audio-progress');\n progressWrapper.append(this.progressLine.container);\n this.wrapper.insertBefore(progressWrapper, this.wrapperUtils);\n\n this.topbar.listenerSetter.add(appMediaPlaybackController)('play', this.onMediaPlay);\n this.topbar.listenerSetter.add(appMediaPlaybackController)('pause', this.onPause);\n this.topbar.listenerSetter.add(appMediaPlaybackController)('stop', this.onStop);\n this.topbar.listenerSetter.add(appMediaPlaybackController)('playbackParams', this.onPlaybackParams);\n\n const playingDetails = appMediaPlaybackController.getPlayingDetails();\n if(playingDetails) {\n this.onMediaPlay(playingDetails);\n this.onPlaybackParams(playingDetails.playbackParams);\n }\n }\n\n public destroy() {\n if(this.progressLine) {\n this.progressLine.removeListeners();\n }\n }\n\n private onPlaybackParams = (playbackParams: ReturnType<AppMediaPlaybackController['getPlaybackParams']>) => {\n this.fasterEl.classList.toggle('active', playbackParams.playbackRate > 1);\n\n this.repeatEl.classList.remove('tgico-audio_repeat', 'tgico-audio_repeat_single');\n this.repeatEl.classList.add(playbackParams.loop ? 'tgico-audio_repeat_single' : 'tgico-audio_repeat');\n this.repeatEl.classList.toggle('active', playbackParams.loop || playbackParams.round);\n };\n\n private onPause = () => {\n this.toggleEl.classList.remove('flip-icon');\n };\n\n private onStop = () => {\n this.toggle(true);\n };\n\n private onMediaPlay = ({doc, message, media, playbackParams}: ReturnType<AppMediaPlaybackController['getPlayingDetails']>) => {\n let title: string | HTMLElement | DocumentFragment, subtitle: string | HTMLElement | DocumentFragment;\n const isMusic = doc.type !== 'voice' && doc.type !== 'round';\n if(!isMusic) {\n title = new PeerTitle({peerId: message.fromId, fromName: message.fwd_from?.from_name}).element;\n\n // subtitle = 'Voice message';\n subtitle = formatFullSentTime(message.date);\n } else {\n const audioAttribute = doc.attributes.find((attr) => attr._ === 'documentAttributeAudio') as DocumentAttribute.documentAttributeAudio;\n title = wrapEmojiText(audioAttribute?.title ?? doc.file_name);\n subtitle = audioAttribute?.performer ? wrapEmojiText(audioAttribute.performer) : i18n('AudioUnknownArtist');\n }\n\n this.fasterEl.classList.toggle('hide', isMusic);\n this.repeatEl.classList.toggle('hide', !isMusic);\n\n this.onPlaybackParams(playbackParams);\n this.volumeSelector.setVolume();\n\n this.progressLine.setMedia({\n media,\n duration: doc.duration\n });\n\n this.fill(title, subtitle, message);\n // this.toggleEl.classList.add('flip-icon');\n this.toggleEl.classList.toggle('flip-icon', !media.paused);\n this.toggle(false);\n };\n}\n","// https://github.com/evgeny-nadymov/telegram-react/blob/master/src/Components/ColumnMiddle/PinnedMessageBorder.js\n\nenum BAR_HEIGHTS {\n ONE = 32,\n TWO = 15,\n THREE = 10,\n FOUR = 8,\n MORE = 8\n};\n\nconst GAP = 1;\nconst WIDTH = 2;\nconst BASE_CLASS = 'pinned-message-border';\n\nexport default class PinnedMessageBorder {\n private border: HTMLElement;\n private wrapper: HTMLElement;\n private svg: SVGSVGElement;\n private defs: SVGDefsElement;\n private clipPath: SVGClipPathElement;\n private path: SVGPathElement;\n private mark: HTMLElement;\n\n private count: number;\n private index: number;\n\n private drawRect = (x: number, y: number, width: number, height: number, radius: number) => {\n return `M${x},${y + radius}a${radius},${radius},0,0,1,${width},0v${height - 2 * radius}a${radius},${radius},0,0,1,${-width},0Z`;\n };\n\n private getClipPath = (id: string, barHeight: number, count: number) => {\n const radius = 1;\n\n let d = '';\n /* if(count === 3) {\n d = this.drawRect(0, 0, WIDTH, barHeight, radius)\n + this.drawRect(0, barHeight + GAP, WIDTH, barHeight + 1, radius)\n + this.drawRect(0, barHeight * 2 + GAP * 2 + 1, WIDTH, barHeight, radius);\n } */if(count === 2) {\n d = this.drawRect(0, 0, WIDTH, barHeight, radius) + this.drawRect(0, barHeight + GAP * 2, WIDTH, barHeight, radius);\n } else {\n for(let i = 0; i < count; ++i) {\n d += this.drawRect(0, (barHeight + GAP) * i, WIDTH, barHeight, radius);\n }\n }\n\n if(!this.clipPath) {\n this.clipPath = document.createElementNS('http://www.w3.org/2000/svg', 'clipPath');\n this.path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n\n this.clipPath.append(this.path);\n }\n\n this.clipPath.id = id;\n this.path.setAttributeNS(null, 'd', d);\n\n return this.clipPath;\n };\n\n private getBarHeight = (count: number, index: number) => {\n let barHeight: number;\n if(count <= 1) {\n barHeight = BAR_HEIGHTS.ONE;\n } else if(count === 2) {\n barHeight = BAR_HEIGHTS.TWO;\n } else if(count === 3) {\n barHeight = BAR_HEIGHTS.THREE;\n } else if(count === 4) {\n barHeight = BAR_HEIGHTS.FOUR;\n } else if(count > 3) {\n barHeight = BAR_HEIGHTS.MORE;\n }\n\n return barHeight;\n };\n\n private getMarkHeight = (count: number, index: number) => {\n let markHeight: number;\n if(count <= 1) {\n markHeight = BAR_HEIGHTS.ONE;\n } else if(count === 2) {\n markHeight = BAR_HEIGHTS.TWO;\n } else if(count === 3) {\n markHeight = BAR_HEIGHTS.THREE;\n } else if(count === 4) {\n markHeight = BAR_HEIGHTS.FOUR;\n } else if(count > 3) {\n markHeight = BAR_HEIGHTS.MORE;\n }\n\n return markHeight;\n };\n\n private getMarkTranslateY = (index: number, barHeight: number, count: number) => {\n if(count === 1) {\n return 0;\n } else if(count === 2) {\n return !index ? 0 : barHeight + GAP;\n }\n\n if(count === 3) {\n if(!index) {\n return 0;\n } else if(index === 1) {\n return barHeight + GAP;\n }\n\n return barHeight * 2 + GAP * 2 + 1;\n } else {\n return (barHeight + GAP) * index;\n }\n };\n\n private getTrackTranslateY = (index: number, count: number, barHeight: number, trackHeight: number) => {\n if(count <= 4) {\n return 0;\n }\n\n if(index <= 1) {\n return 0;\n } else if(index >= (count - 2)) {\n return trackHeight - BAR_HEIGHTS.ONE - barHeight;\n }\n\n // return (index + 1) * barHeight + index * GAP;\n return (index - 2) * barHeight + index * GAP;\n // return (barHeight + GAP * 2) / 2 + (index - 2) * (barHeight + GAP);\n };\n\n private getTrackHeight = (count: number, barHeight: number) => {\n return count <= 3 ? BAR_HEIGHTS.ONE : barHeight * count + GAP * (count - 1);\n };\n\n public render(count: number, index: number) {\n if(!this.border) {\n this.border = document.createElement('div');\n this.border.classList.add(BASE_CLASS);\n\n this.wrapper = document.createElement('div');\n this.border.append(this.wrapper);\n }\n\n if(count === 1) {\n if(this.count !== count) {\n this.wrapper.className = BASE_CLASS + '-wrapper-1';\n this.border.classList.remove(BASE_CLASS + '-mask');\n this.wrapper.replaceChildren();\n this.wrapper.style.cssText = '';\n }\n\n return this.border;\n }\n\n const barHeight = this.getBarHeight(count, index);\n const markHeight = this.getMarkHeight(count, index);\n const trackHeight = this.getTrackHeight(count, barHeight);\n\n const clipPathId = `clipPath_${count}`;\n const clipPath = this.getClipPath(clipPathId, barHeight, count);\n\n const markTranslateY = this.getMarkTranslateY(index, barHeight, count);\n const trackTranslateY = this.getTrackTranslateY(index, count, barHeight, trackHeight);\n\n this.border.classList.toggle(BASE_CLASS + '-mask', count > 4);\n\n if(index <= 1) {\n this.border.classList.add('mask-bottom');\n this.border.classList.remove('mask-top');\n } else if(index >= (count - 2)) {\n this.border.classList.add('mask-top');\n this.border.classList.remove('mask-bottom');\n } else {\n this.border.classList.add('mask-top', 'mask-bottom');\n }\n\n this.wrapper.className = BASE_CLASS + '-wrapper';\n this.wrapper.style.cssText = `clip-path: url(#${clipPathId}); width: 2px; height: ${trackHeight}px; transform: translateY(-${trackTranslateY}px);`;\n\n if(!this.svg) {\n this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n this.svg.setAttributeNS(null, 'height', '0');\n this.svg.setAttributeNS(null, 'width', '0');\n\n this.defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n this.defs.append(clipPath);\n\n this.svg.append(this.defs);\n\n this.mark = document.createElement('div');\n this.mark.classList.add(BASE_CLASS + '-mark');\n }\n\n if(!this.svg.parentElement) {\n this.wrapper.append(this.svg, this.mark);\n }\n\n this.mark.style.cssText = `height: ${markHeight}px; transform: translateY(${markTranslateY}px);`;\n\n this.count = count;\n this.index = index;\n\n return this.border;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ChatTopbar from './topbar';\nimport PopupPinMessage from '../popups/unpinMessage';\nimport PinnedContainer from './pinnedContainer';\nimport PinnedMessageBorder from './pinnedMessageBorder';\nimport ReplyContainer, {wrapReplyDivAndCaption} from './replyContainer';\nimport rootScope from '../../lib/rootScope';\nimport Chat from './chat';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport ButtonIcon from '../buttonIcon';\nimport {getHeavyAnimationPromise} from '../../hooks/useHeavyAnimationCheck';\nimport {i18n} from '../../lib/langPack';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport handleScrollSideEvent from '../../helpers/dom/handleScrollSideEvent';\nimport debounce from '../../helpers/schedulers/debounce';\nimport throttle from '../../helpers/schedulers/throttle';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport {Message} from '../../layer';\nimport {logger} from '../../lib/logger';\nimport PopupElement from '../popups';\n\nclass AnimatedSuper {\n static DURATION = 200;\n static BASE_CLASS = 'animated-super';\n container: HTMLDivElement;\n rows: {[index: string]: {element: HTMLElement, timeout?: number, new?: true}} = {};\n clearTimeout: number;\n\n constructor() {\n this.container = document.createElement('div');\n this.container.className = AnimatedSuper.BASE_CLASS;\n }\n\n public getRow(index: number, animateFirst = false) {\n if(this.rows[index]) return this.rows[index].element;\n const row = document.createElement('div');\n const isFirst = !Object.keys(this.rows).length && !animateFirst;\n row.className = AnimatedSuper.BASE_CLASS + '-row' + (isFirst ? '' : ' is-hiding hide');\n this.rows[index] = {element: row, new: true};\n this.container.append(row);\n return row;\n }\n\n public clearRow(index: number) {\n if(!this.rows[index]) return;\n this.rows[index].element.remove();\n delete this.rows[index];\n }\n\n public clearRows(currentIndex?: number) {\n if(this.clearTimeout) clearTimeout(this.clearTimeout);\n this.clearTimeout = window.setTimeout(() => {\n for(const i in this.rows) {\n if(+i === currentIndex) continue;\n this.clearRow(+i);\n }\n }, AnimatedSuper.DURATION);\n }\n\n public setNewRow(index: number, reflow = false) {\n const row = this.rows[index];\n if(row.new) {\n if(reflow) {\n row.element.classList.remove('hide');\n void row.element.offsetLeft; // reflow\n } else {\n row.element.classList.remove('is-hiding', 'hide');\n }\n\n delete row.new;\n }\n\n this.clearRows(index);\n }\n\n public animate(index: number, previousIndex: number, fromTop = index > previousIndex, ignorePrevious = false) {\n if(index === previousIndex) { // * handle if set index 0 and previousIndex 0\n return this.setNewRow(index);\n }\n\n const row = this.rows[index];\n const previousRow = this.rows[previousIndex];\n if(!previousRow && !ignorePrevious) {\n return this.setNewRow(index);\n }\n\n const sides = ['from-top', 'from-bottom'];\n if(!fromTop) sides.reverse();\n\n row.element.classList.add(sides[0]);\n row.element.classList.remove(sides[1]);\n if(previousRow) {\n previousRow.element.classList.add(sides[1]);\n previousRow.element.classList.remove(sides[0]);\n }\n\n if(row.new) {\n this.setNewRow(index, true);\n }\n\n row.element.classList.toggle('is-hiding', false);\n previousRow && previousRow.element.classList.toggle('is-hiding', true);\n\n /* const height = row.element.getBoundingClientRect().height;\n row.element.style.transform = `translateY(${fromTop ? height * -1 : height}px)`;\n if(previousRow) {\n previousRow.element.style.transform = `translateY(${fromTop ? height : height * -1}px)`;\n } */\n\n /* row.element.style.setProperty('--height', row.element.getBoundingClientRect().height + 'px');\n if(previousRow) {\n previousRow.element.style.setProperty('--height', previousRow.element.getBoundingClientRect().height + 'px');\n } */\n\n this.clearRows(index);\n }\n}\n\nclass AnimatedCounter {\n static EMPTY_INDEX = -1;\n static BASE_CLASS = 'animated-counter';\n container: HTMLElement;\n decimals: {\n container: HTMLElement,\n placeholder: HTMLElement,\n animatedSuper: AnimatedSuper\n }[] = [];\n previousNumber = 0;\n clearTimeout: number;\n\n constructor(private reverse = false) {\n this.container = document.createElement('div');\n this.container.className = AnimatedCounter.BASE_CLASS;\n }\n\n getDecimal(index: number) {\n if(this.decimals[index]) return this.decimals[index];\n const item = document.createElement('div');\n item.className = AnimatedCounter.BASE_CLASS + '-decimal';\n\n const placeholder = document.createElement('div');\n placeholder.className = AnimatedCounter.BASE_CLASS + '-decimal-placeholder';\n\n const animatedSuper = new AnimatedSuper();\n animatedSuper.container.className = AnimatedCounter.BASE_CLASS + '-decimal-wrapper';\n\n item.append(placeholder, animatedSuper.container);\n\n this.container.append(item);\n\n return this.decimals[index] = {container: item, placeholder, animatedSuper};\n }\n\n clear(number: number) {\n if(this.clearTimeout) clearTimeout(this.clearTimeout);\n\n const decimals = ('' + number).length;\n if(decimals >= this.decimals.length) {\n return;\n }\n\n this.clearTimeout = window.setTimeout(() => {\n const byDecimal = this.decimals.splice(decimals, this.decimals.length - decimals);\n byDecimal.forEach((decimal) => {\n decimal.container.remove();\n });\n }, AnimatedSuper.DURATION);\n }\n\n /* prepareNumber(number: number) {\n const decimals = ('' + number).length;\n if(this.decimals.length < decimals) {\n for(let i = this.decimals.length; i < decimals; ++i) {\n this.getDecimal(i);\n }\n }\n } */\n\n hideLeft(number: number) {\n const decimals = ('' + number).length;\n const byDecimal = this.decimals.slice(decimals);// this.decimals.splice(deleteCount, this.decimals.length - deleteCount);\n byDecimal.forEach((decimal) => {\n const previousDecimalNumber = +decimal.placeholder.innerText || 0;\n const row = decimal.animatedSuper.getRow(AnimatedCounter.EMPTY_INDEX, true);\n decimal.animatedSuper.animate(AnimatedCounter.EMPTY_INDEX, previousDecimalNumber, this.reverse ? number < this.previousNumber : number > this.previousNumber, true);\n });\n\n this.clear(number);\n }\n\n setCount(number: number) {\n // this.prepareNumber(number);\n\n const previousByDecimal = Array.from('' + this.previousNumber).map((n) => +n);\n const byDecimal = Array.from('' + number).map((n) => +n);\n byDecimal.forEach((decimalNumber, idx) => {\n const decimal = this.getDecimal(idx);\n // const row = decimal.animatedSuper.getRow(number, true);\n const row = decimal.animatedSuper.getRow(decimalNumber, true);\n const previousDecimalNumber = previousByDecimal[idx] ?? AnimatedCounter.EMPTY_INDEX;\n row.innerText = decimal.placeholder.innerText = '' + decimalNumber;\n // decimal.animatedSuper.animate(number, this.previousNumber, this.reverse ? number < this.previousNumber : number > this.previousNumber, true);\n decimal.animatedSuper.animate(decimalNumber, previousDecimalNumber, this.reverse ? number < this.previousNumber : number > this.previousNumber, true);\n });\n\n this.hideLeft(number);\n // this.clear(number);\n this.previousNumber = number;\n }\n}\n\nexport default class ChatPinnedMessage {\n private static LOAD_COUNT = 50;\n private static LOAD_OFFSET = 5;\n\n public pinnedMessageContainer: PinnedContainer;\n private pinnedMessageBorder: PinnedMessageBorder;\n\n private pinnedMaxMid = 0;\n public pinnedMid = 0;\n public pinnedIndex = -1;\n private wasPinnedIndex = 0;\n private wasPinnedMediaIndex = 0;\n\n public locked = false;\n private waitForScrollBottom = false;\n\n public count = 0;\n private mids: number[] = [];\n private offsetIndex = 0;\n\n private loading = false;\n private loadedBottom = false;\n private loadedTop = false;\n\n private animatedSubtitle: AnimatedSuper;\n private animatedMedia: AnimatedSuper;\n private animatedCounter: AnimatedCounter;\n\n private listenerSetter: ListenerSetter;\n private scrollDownListenerSetter: ListenerSetter = null;\n\n public hidden = false;\n\n private getCurrentIndexPromise: Promise<any> = null;\n private btnOpen: HTMLButtonElement;\n\n private setPinnedMessage: () => void;\n\n private isStatic: boolean;\n\n private debug: boolean;\n\n public setCorrectIndexThrottled: (lastScrollDirection?: number) => void;\n\n private log: ReturnType<typeof logger>;\n\n constructor(private topbar: ChatTopbar, private chat: Chat, private managers: AppManagers) {\n this.listenerSetter = new ListenerSetter();\n this.log = logger('PM');\n this.debug = true;\n this.isStatic = false;\n\n const dAC = new ReplyContainer('pinned-message', chat.animationGroup);\n this.pinnedMessageContainer = new PinnedContainer({\n topbar,\n chat,\n listenerSetter: this.listenerSetter,\n className: 'message',\n divAndCaption: dAC,\n onClose: async() => {\n if(await managers.appPeersManager.canPinMessage(this.chat.peerId)) {\n PopupElement.createPopup(PopupPinMessage, this.chat.peerId, this.pinnedMid, true);\n } else {\n PopupElement.createPopup(PopupPinMessage, this.chat.peerId, 0, true);\n }\n\n return false;\n }\n });\n\n this.pinnedMessageBorder = new PinnedMessageBorder();\n dAC.border.replaceWith(this.pinnedMessageBorder.render(1, 0));\n\n this.animatedSubtitle = new AnimatedSuper();\n dAC.subtitle.append(this.animatedSubtitle.container);\n\n this.animatedMedia = new AnimatedSuper();\n this.animatedMedia.container.classList.add('pinned-message-media-container');\n dAC.content.prepend(this.animatedMedia.container);\n\n this.animatedCounter = new AnimatedCounter(true);\n dAC.title.append(i18n('PinnedMessage'), ' ', this.animatedCounter.container);\n\n const btnClose = this.pinnedMessageContainer.btnClose.cloneNode(true) as HTMLElement;\n this.pinnedMessageContainer.attachOnCloseEvent(btnClose);\n dAC.container.prepend(btnClose);\n\n this.btnOpen = ButtonIcon('pinlist pinned-container-close pinned-message-pinlist', {noRipple: true});\n\n this.pinnedMessageContainer.wrapperUtils.prepend(this.btnOpen);\n\n attachClickEvent(this.btnOpen, (e) => {\n cancelEvent(e);\n this.topbar.openPinned(true);\n }, {listenerSetter: this.listenerSetter});\n\n this.listenerSetter.add(rootScope)('peer_pinned_messages', ({peerId}) => {\n if(peerId === this.chat.peerId) {\n // this.wasPinnedIndex = 0;\n // setTimeout(() => {\n if(this.hidden) {\n this.pinnedMessageContainer.toggle(this.hidden = false);\n }\n\n this.loadedTop = this.loadedBottom = false;\n this.pinnedIndex = -1;\n this.pinnedMid = 0;\n this.count = 0;\n this.mids = [];\n this.offsetIndex = 0;\n this.pinnedMaxMid = 0;\n this.setCorrectIndex(0);\n // }, 300);\n }\n });\n\n this.listenerSetter.add(rootScope)('peer_pinned_hidden', ({peerId}) => {\n if(peerId === this.chat.peerId) {\n this.pinnedMessageContainer.toggle(this.hidden = true);\n }\n });\n\n // * 200 - no lags\n // * 100 - need test\n this.setPinnedMessage = debounce(() => this._setPinnedMessage(), 100, true, true);\n this.setCorrectIndexThrottled = throttle(this.setCorrectIndex.bind(this), 100, false);\n\n this.isStatic = !this.chat.isPinnedMessagesNeeded();\n }\n\n public destroy() {\n this.pinnedMessageContainer.divAndCaption.container.remove();\n this.pinnedMessageContainer.toggle(true);\n this.listenerSetter.removeAll();\n this.unsetScrollDownListener(false);\n }\n\n public setCorrectIndex(lastScrollDirection?: number) {\n if(this.isStatic) return;\n // return;\n\n if(this.locked || this.hidden/* || this.chat.setPeerPromise || this.chat.bubbles.messagesQueuePromise */) {\n return;\n }\n\n if((this.loadedBottom || this.loadedTop) && !this.count) {\n return;\n }\n\n // const perf = performance.now();\n const el = this.chat.bubbles.getBubbleByPoint('bottom');\n // this.log('setCorrectIndex: get last element perf:', performance.now() - perf, el);\n if(!el) return;\n\n // return;\n\n const mid = el.dataset.mid;\n if(el && mid !== undefined) {\n // this.log('setCorrectIndex will test mid:', mid);\n this.testMid(+mid, lastScrollDirection);\n }\n }\n\n public testMid(mid: number, lastScrollDirection?: number) {\n if(this.isStatic) return;\n\n // if(lastScrollDirection !== undefined) return;\n if(this.hidden) return;\n\n // this.log('testMid', mid);\n\n let currentIndex: number = this.mids.findIndex((_mid) => _mid <= mid);\n if(currentIndex !== -1 && !this.isNeededMore(currentIndex)) {\n currentIndex += this.offsetIndex;\n } else if(this.loadedTop && mid < this.mids[this.mids.length - 1]) {\n // currentIndex = 0;\n currentIndex = this.mids.length - 1 + this.offsetIndex;\n } else {\n if(!this.getCurrentIndexPromise) {\n this.getCurrentIndexPromise = this.getCurrentIndex(mid, lastScrollDirection !== undefined);\n }\n\n return;\n }\n\n // const idx = Math.max(0, this.mids.indexOf(mid));\n\n /* if(currentIndex === this.count) {\n currentIndex = 0;\n } */\n\n // this.log('testMid: pinned currentIndex', currentIndex, mid);\n\n const changed = this.pinnedIndex !== currentIndex;\n if(changed) {\n if(this.waitForScrollBottom && lastScrollDirection !== undefined) {\n if(this.pinnedIndex === 0 || this.pinnedIndex > currentIndex) { // если не скроллил вниз и пытается поставить нижний пиннед - выйти\n return;\n }\n }\n\n this.pinnedIndex = currentIndex;\n this.pinnedMid = this.mids.find((_mid) => _mid <= mid) || this.mids[this.mids.length - 1];\n this.setPinnedMessage();\n }\n }\n\n private isNeededMore(currentIndex: number) {\n return (this.count > ChatPinnedMessage.LOAD_COUNT &&\n (\n (!this.loadedBottom && currentIndex <= ChatPinnedMessage.LOAD_OFFSET) ||\n (!this.loadedTop && (this.count - 1 - currentIndex) <= ChatPinnedMessage.LOAD_OFFSET)\n )\n );\n }\n\n private async getCurrentIndex(mid: number, correctAfter = true) {\n if(this.loading) return;\n this.loading = true;\n\n try {\n const log = this.debug ? this.log.bindPrefix('getCurrentIndex') : undefined;\n log && log('start', mid, correctAfter);\n\n let gotRest = false;\n const promises = [\n this.managers.appMessagesManager.getSearch({\n peerId: this.chat.peerId,\n inputFilter: {_: 'inputMessagesFilterPinned'},\n maxId: mid,\n limit: ChatPinnedMessage.LOAD_COUNT,\n backLimit: ChatPinnedMessage.LOAD_COUNT,\n threadId: this.chat.threadId\n })\n .then((r) => {\n gotRest = true;\n return r;\n })\n ];\n\n if(!this.pinnedMaxMid) {\n const promise = this.managers.appMessagesManager.getPinnedMessage(this.chat.peerId, this.chat.threadId).then((p) => {\n if(!p.maxId) return;\n this.pinnedMaxMid = p.maxId;\n\n if(!gotRest && correctAfter) {\n this.mids = [this.pinnedMaxMid];\n this.count = p.count;\n this.pinnedIndex = 0;\n this.pinnedMid = this.mids[0];\n this.setPinnedMessage();\n // this.pinnedMessageContainer.toggle(false);\n }\n });\n\n promises.push(promise as any);\n }\n\n const result = (await Promise.all(promises))[0];\n\n let backLimited = result.history.findIndex((message) => message.mid <= mid);\n if(backLimited === -1) {\n backLimited = result.history.length;\n }/* else {\n backLimited -= 1;\n } */\n\n this.offsetIndex = result.offset_id_offset ? result.offset_id_offset - backLimited : 0;\n this.mids = result.history.map((message) => message.mid).slice();\n this.count = result.count;\n\n if(!this.count) {\n this.pinnedMessageContainer.toggle(true);\n }\n\n this.loadedTop = (this.offsetIndex + this.mids.length) === this.count;\n this.loadedBottom = !this.offsetIndex;\n\n log && log('result', mid, result, backLimited, this.offsetIndex, this.loadedTop, this.loadedBottom);\n } catch(err) {\n this.log.error('getCurrentIndex error', err);\n }\n\n this.loading = false;\n\n if(this.locked) {\n this.testMid(mid);\n } else if(correctAfter) {\n this.setCorrectIndex(0);\n }\n\n this.getCurrentIndexPromise = null;\n // return result.offset_id_offset || 0;\n }\n\n public setScrollDownListener() {\n this.waitForScrollBottom = true;\n\n if(!this.scrollDownListenerSetter) {\n this.scrollDownListenerSetter = new ListenerSetter();\n handleScrollSideEvent(this.chat.bubbles.scrollable.container, 'bottom', () => {\n this.unsetScrollDownListener();\n }, this.scrollDownListenerSetter);\n }\n }\n\n public unsetScrollDownListener(refreshPosition = true) {\n this.waitForScrollBottom = false;\n\n if(this.scrollDownListenerSetter) {\n this.scrollDownListenerSetter.removeAll();\n this.scrollDownListenerSetter = null;\n }\n\n if(refreshPosition) {\n this.setCorrectIndex(0);\n }\n }\n\n public async handleFollowingPinnedMessage() {\n this.locked = true;\n\n this.debug && this.log('handleFollowingPinnedMessage');\n try {\n this.setScrollDownListener();\n\n const setPeerPromise = this.chat.setPeerPromise;\n if(setPeerPromise instanceof Promise) {\n await setPeerPromise;\n }\n\n // await this.chat.bubbles.scrollable.scrollLockedPromise;\n await getHeavyAnimationPromise();\n\n if(this.getCurrentIndexPromise) {\n await this.getCurrentIndexPromise;\n }\n\n this.debug && this.log('handleFollowingPinnedMessage: unlock');\n this.locked = false;\n\n /* // подождём, пока скролл остановится\n setTimeout(() => {\n this.log('handleFollowingPinnedMessage: unlock');\n this.locked = false;\n }, 50); */\n } catch(err) {\n this.log.error('handleFollowingPinnedMessage error:', err);\n\n this.locked = false;\n this.waitForScrollBottom = false;\n this.setCorrectIndex(0);\n }\n }\n\n public async followPinnedMessage(mid: number) {\n const message = await this.chat.getMessage(mid);\n if(!message) {\n return;\n }\n\n this.chat.setMessageId(mid);\n (this.chat.setPeerPromise || Promise.resolve()).then(() => { // * debounce fast clicker\n this.handleFollowingPinnedMessage();\n this.testMid(this.pinnedIndex >= (this.count - 1) ? this.pinnedMaxMid : mid - 1);\n });\n }\n\n public async _setPinnedMessage() {\n // ///this.log('setting pinned message', message);\n // return;\n /* const promise: Promise<any> = this.chat.setPeerPromise || this.chat.bubbles.messagesQueuePromise || Promise.resolve();\n Promise.all([\n promise\n ]).then(() => { */\n // const mids = results[0];\n const count = this.count;\n if(count) {\n const pinnedIndex = this.pinnedIndex;\n const message = await this.chat.getMessage(this.pinnedMid);\n\n // this.animatedCounter.prepareNumber(count);\n\n // setTimeout(() => {\n const isLast = pinnedIndex === 0;\n this.animatedCounter.container.classList.toggle('is-last', isLast);\n // SetTransition(this.animatedCounter.container, 'is-last', isLast, AnimatedSuper.DURATION);\n if(!isLast) {\n this.animatedCounter.setCount(count - pinnedIndex);\n }\n // }, 100);\n\n // this.pinnedMessageContainer.fill(undefined, message.message, message);\n this.pinnedMessageContainer.toggle(false);\n\n const fromTop = pinnedIndex > this.wasPinnedIndex;\n\n this.debug && this.log('setPinnedMessage: fromTop', fromTop, pinnedIndex, this.wasPinnedIndex);\n\n const writeTo = this.animatedSubtitle.getRow(pinnedIndex);\n const writeMediaTo = this.animatedMedia.getRow(pinnedIndex);\n writeMediaTo.classList.add('pinned-message-media');\n // writeMediaTo.innerHTML = writeMediaTo.style.cssText = writeMediaTo.dataset.docId = '';\n const loadPromises: Promise<any>[] = [];\n const isMediaSet = await wrapReplyDivAndCaption({\n title: undefined,\n titleEl: null,\n subtitle: (message as Message.message).message,\n subtitleEl: writeTo,\n message,\n mediaEl: writeMediaTo,\n loadPromises,\n animationGroup: this.chat.animationGroup\n });\n\n await Promise.all(loadPromises);\n\n this.pinnedMessageContainer.divAndCaption.container.classList.toggle('is-media', isMediaSet);\n\n // if(this.wasPinnedIndex !== this.pinnedIndex) {\n this.animatedSubtitle.animate(pinnedIndex, this.wasPinnedIndex);\n if(isMediaSet) {\n this.animatedMedia.animate(pinnedIndex, this.wasPinnedMediaIndex); // * wasPinnedMediaIndex из-за того, что блок меняется с другим алгоритмом\n this.wasPinnedMediaIndex = pinnedIndex;\n } else {\n this.animatedMedia.clearRows();\n }\n // }\n\n this.pinnedMessageBorder.render(count, count - pinnedIndex - 1);\n this.wasPinnedIndex = pinnedIndex;\n this.pinnedMessageContainer.divAndCaption.container.dataset.mid = '' + message.mid;\n } else {\n this.pinnedMessageContainer.toggle(true);\n this.wasPinnedIndex = 0;\n }\n\n this.pinnedMessageContainer.divAndCaption.container.classList.toggle('is-many', this.count > 1);\n // });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ListenerSetter from '../listenerSetter';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\n\nexport default function handleScrollSideEvent(elem: HTMLElement, side: 'top' | 'bottom', callback: () => void, listenerSetter: ListenerSetter) {\n if(IS_TOUCH_SUPPORTED) {\n let lastY: number;\n const options = {passive: true};\n listenerSetter.add(elem)('touchstart', (e) => {\n if(e.touches.length > 1) {\n onTouchEnd();\n return;\n }\n\n lastY = e.touches[0].clientY;\n\n listenerSetter.add(elem)('touchmove', onTouchMove, options);\n listenerSetter.add(elem)('touchend', onTouchEnd, options);\n }, options);\n\n const onTouchMove = (e: TouchEvent) => {\n const clientY = e.touches[0].clientY;\n\n const isDown = clientY < lastY;\n if(side === 'bottom' && isDown) callback();\n else if(side === 'top' && !isDown) callback();\n lastY = clientY;\n // alert('isDown: ' + !!isDown);\n };\n\n const onTouchEnd = () => {\n listenerSetter.removeManual(elem, 'touchmove', onTouchMove, options);\n listenerSetter.removeManual(elem, 'touchend', onTouchEnd, options);\n };\n } else {\n listenerSetter.add(elem)('wheel', (e) => {\n const isDown = e.deltaY > 0;\n // this.log('wheel', e, isDown);\n if(side === 'bottom' && isDown) callback();\n else if(side === 'top' && !isDown) callback();\n }, {passive: true});\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {Channel} from '../../lib/appManagers/appChatsManager';\nimport type {AppSidebarRight} from '../sidebarRight';\nimport type Chat from './chat';\nimport {RIGHT_COLUMN_ACTIVE_CLASSNAME} from '../sidebarRight';\nimport mediaSizes, {ScreenSize} from '../../helpers/mediaSizes';\nimport {IS_SAFARI} from '../../environment/userAgent';\nimport rootScope from '../../lib/rootScope';\nimport AvatarElement from '../avatar';\nimport Button from '../button';\nimport ButtonIcon from '../buttonIcon';\nimport ButtonMenuToggle from '../buttonMenuToggle';\nimport ChatAudio from './audio';\nimport ChatPinnedMessage from './pinnedMessage';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport PopupDeleteDialog from '../popups/deleteDialog';\nimport appNavigationController from '../appNavigationController';\nimport {LEFT_COLUMN_ACTIVE_CLASSNAME} from '../sidebarLeft';\nimport PeerTitle from '../peerTitle';\nimport {i18n} from '../../lib/langPack';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport blurActiveElement from '../../helpers/dom/blurActiveElement';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport findUpTag from '../../helpers/dom/findUpTag';\nimport {toast, toastNew} from '../toast';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport {ChatFull, Chat as MTChat, GroupCall} from '../../layer';\nimport PopupPickUser from '../popups/pickUser';\nimport PopupPeer from '../popups/peer';\nimport AppEditContactTab from '../sidebarRight/tabs/editContact';\nimport appMediaPlaybackController from '../appMediaPlaybackController';\nimport IS_GROUP_CALL_SUPPORTED from '../../environment/groupCallSupport';\nimport IS_CALL_SUPPORTED from '../../environment/callSupport';\nimport {CallType} from '../../lib/calls/types';\nimport PopupMute from '../popups/mute';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport hasRights from '../../lib/appManagers/utils/chats/hasRights';\nimport wrapPeerTitle from '../wrappers/peerTitle';\nimport groupCallsController from '../../lib/calls/groupCallsController';\nimport apiManagerProxy from '../../lib/mtproto/mtprotoworker';\nimport {makeMediaSize} from '../../helpers/mediaSize';\nimport {FOLDER_ID_ALL} from '../../lib/mtproto/mtproto_config';\nimport formatNumber from '../../helpers/number/formatNumber';\nimport PopupElement from '../popups';\n\ntype ButtonToVerify = {element?: HTMLElement, verify: () => boolean | Promise<boolean>};\n\nexport default class ChatTopbar {\n public container: HTMLDivElement;\n private btnBack: HTMLButtonElement;\n private btnBackBadge: HTMLElement;\n private chatInfo: HTMLDivElement;\n private avatarElement: AvatarElement;\n private title: HTMLDivElement;\n private subtitle: HTMLDivElement;\n private chatUtils: HTMLDivElement;\n private btnJoin: HTMLButtonElement;\n private btnPinned: HTMLButtonElement;\n private btnCall: HTMLButtonElement;\n private btnGroupCall: HTMLButtonElement;\n private btnMute: HTMLButtonElement;\n private btnSearch: HTMLButtonElement;\n private btnMore: HTMLElement;\n\n private chatAudio: ChatAudio;\n public pinnedMessage: ChatPinnedMessage;\n\n private setUtilsRAF: number;\n private setPeerStatusInterval: number;\n\n public listenerSetter: ListenerSetter;\n\n private menuButtons: Parameters<typeof ButtonMenuToggle>[0]['buttons'];\n private buttonsToVerify: ButtonToVerify[];\n private chatInfoContainer: HTMLDivElement;\n private person: HTMLDivElement;\n\n constructor(\n private chat: Chat,\n private appSidebarRight: AppSidebarRight,\n private managers: AppManagers\n ) {\n this.listenerSetter = new ListenerSetter();\n\n this.menuButtons = [];\n this.buttonsToVerify = [];\n }\n\n public construct() {\n // this.chat.log.error('Topbar construction');\n\n this.container = document.createElement('div');\n this.container.classList.add('sidebar-header', 'topbar', 'hide');\n this.container.dataset.floating = '0';\n\n this.btnBack = ButtonIcon('left sidebar-close-button', {noRipple: true});\n this.btnBackBadge = document.createElement('span');\n this.btnBackBadge.classList.add('badge', 'badge-20', 'badge-primary', 'back-unread-badge');\n this.btnBack.append(this.btnBackBadge);\n\n // * chat info section\n this.chatInfoContainer = document.createElement('div');\n this.chatInfoContainer.classList.add('chat-info-container');\n\n this.chatInfo = document.createElement('div');\n this.chatInfo.classList.add('chat-info');\n\n const person = this.person = document.createElement('div');\n person.classList.add('person');\n\n const content = document.createElement('div');\n content.classList.add('content');\n\n const top = document.createElement('div');\n top.classList.add('top');\n\n this.title = document.createElement('div');\n this.title.classList.add('user-title');\n\n top.append(this.title);\n\n const bottom = document.createElement('div');\n bottom.classList.add('bottom');\n\n if(this.subtitle) {\n bottom.append(this.subtitle);\n }\n\n content.append(top, bottom);\n if(this.avatarElement) {\n person.append(this.avatarElement);\n }\n\n person.append(content);\n this.chatInfo.append(person);\n\n // * chat utils section\n this.chatUtils = document.createElement('div');\n this.chatUtils.classList.add('chat-utils');\n\n this.chatAudio = new ChatAudio(this, this.chat, this.managers);\n\n if(this.menuButtons.length) {\n this.btnMore = ButtonMenuToggle({\n listenerSetter: this.listenerSetter,\n direction: 'bottom-left',\n buttons: this.menuButtons,\n onOpen: async(e, element) => {\n const deleteButton = this.menuButtons[this.menuButtons.length - 1];\n if(deleteButton?.element) {\n const deleteButtonText = await this.managers.appPeersManager.getDeleteButtonText(this.peerId);\n deleteButton.element.lastChild.replaceWith(i18n(deleteButtonText));\n }\n }\n });\n }\n\n this.chatUtils.append(...[\n // this.chatAudio ? this.chatAudio.divAndCaption.container : null,\n this.pinnedMessage ? this.pinnedMessage.pinnedMessageContainer.divAndCaption.container : null,\n this.btnJoin,\n this.btnPinned,\n this.btnCall,\n this.btnGroupCall,\n this.btnMute,\n this.btnSearch,\n this.btnMore\n ].filter(Boolean));\n\n this.pushButtonToVerify(this.btnCall, this.verifyCallButton.bind(this, 'voice'));\n this.pushButtonToVerify(this.btnGroupCall, this.verifyVideoChatButton);\n\n this.chatInfoContainer.append(this.btnBack, this.chatInfo, this.chatUtils);\n this.container.append(this.chatInfoContainer);\n\n if(this.chatAudio) {\n // this.container.append(this.chatAudio.divAndCaption.container, this.chatUtils);\n this.container.append(this.chatAudio.divAndCaption.container);\n }\n\n // * construction end\n\n // * fix topbar overflow section\n\n this.listenerSetter.add(window)('resize', this.onResize);\n this.listenerSetter.add(mediaSizes)('changeScreen', this.onChangeScreen);\n\n attachClickEvent(this.container, (e) => {\n const container = findUpClassName(e.target, 'pinned-container');\n blurActiveElement();\n if(container) {\n cancelEvent(e);\n\n if(findUpClassName(e.target, 'progress-line') || findUpClassName(e.target, 'pinned-container-wrapper-utils')) {\n return;\n }\n\n const mid = +container.dataset.mid;\n if(container.classList.contains('pinned-message')) {\n // if(!this.pinnedMessage.locked) {\n this.pinnedMessage.followPinnedMessage(mid);\n // }\n } else {\n const peerId = container.dataset.peerId.toPeerId();\n const searchContext = appMediaPlaybackController.getSearchContext();\n this.chat.appImManager.setInnerPeer({\n peerId,\n lastMsgId: mid,\n type: searchContext.isScheduled ? 'scheduled' : (searchContext.threadId ? 'discussion' : undefined),\n threadId: searchContext.threadId\n });\n }\n } else {\n if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) {\n onBtnBackClick();\n } else if(findUpTag(e.target, 'AVATAR-ELEMENT')) {\n this.appSidebarRight.toggleSidebar(!document.body.classList.contains(RIGHT_COLUMN_ACTIVE_CLASSNAME));\n } else {\n this.appSidebarRight.toggleSidebar(true);\n }\n }\n }, {listenerSetter: this.listenerSetter});\n\n const onBtnBackClick = (e?: Event) => {\n if(e) {\n cancelEvent(e);\n }\n\n // const item = appNavigationController.findItemByType('chat');\n // * return manually to chat by arrow, since can't get back to\n if(mediaSizes.activeScreen === ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) {\n this.chat.appImManager.setPeer({peerId: this.peerId});\n } else {\n const isFirstChat = this.chat.appImManager.chats.indexOf(this.chat) === 0;\n appNavigationController.back(isFirstChat ? 'im' : 'chat');\n /* return;\n\n if(mediaSizes.activeScreen === ScreenSize.medium && !appNavigationController.findItemByType('chat')) {\n this.chat.appImManager.setPeer(0);\n blurActiveElement();\n } else {\n appNavigationController.back('chat');\n } */\n }\n };\n\n attachClickEvent(this.btnBack, onBtnBackClick, {listenerSetter: this.listenerSetter});\n }\n\n private pushButtonToVerify(element: HTMLElement, verify: ButtonToVerify['verify']) {\n if(!element) {\n return;\n }\n\n this.buttonsToVerify.push({element, verify});\n }\n\n private verifyButtons = (e?: Event) => {\n const isMenuOpen = !!e || !!(this.btnMore && this.btnMore.classList.contains('menu-open'));\n\n e && cancelEvent(e);\n\n const r = async() => {\n const buttons = this.buttonsToVerify.concat(isMenuOpen ? this.menuButtons as any : []);\n const results = await Promise.all(buttons.map(async(button) => {\n return {\n result: await button.verify(),\n button\n }\n }));\n\n results.forEach(({button, result}) => {\n button.element.classList.toggle('hide', !result);\n });\n };\n\n r();\n };\n\n private verifyVideoChatButton = async(type?: 'group' | 'broadcast') => {\n if(!IS_GROUP_CALL_SUPPORTED || this.peerId.isUser() || this.chat.type !== 'chat' || this.chat.threadId) return false;\n\n const currentGroupCall = groupCallsController.groupCall;\n const chatId = this.peerId.toChatId();\n if(currentGroupCall?.chatId === chatId) {\n return false;\n }\n\n if(type) {\n if(((await this.managers.appPeersManager.isBroadcast(this.peerId)) && type === 'group') ||\n ((await this.managers.appPeersManager.isAnyGroup(this.peerId)) && type === 'broadcast')) {\n return false;\n }\n }\n\n const chat = await this.managers.appChatsManager.getChat(chatId);\n return (chat as MTChat.chat).pFlags?.call_active || hasRights(chat, 'manage_call');\n };\n\n private verifyCallButton = async(type?: CallType) => {\n if(!IS_CALL_SUPPORTED || !this.peerId.isUser()) return false;\n const userId = this.peerId.toUserId();\n const userFull = await this.managers.appProfileManager.getCachedFullUser(userId);\n\n return !!userFull && !!(type === 'voice' ? userFull.pFlags.phone_calls_available : userFull.pFlags.video_calls_available);\n };\n\n public constructUtils() {\n this.menuButtons = [{\n icon: 'search',\n text: 'Search',\n onClick: () => {\n this.chat.initSearch();\n },\n verify: () => mediaSizes.isMobile\n }, /* {\n icon: 'pinlist',\n text: 'Pinned Messages',\n onClick: () => this.openPinned(false),\n verify: () => mediaSizes.isMobile\n }, */{\n icon: 'mute',\n text: 'ChatList.Context.Mute',\n onClick: this.onMuteClick,\n verify: async() => this.chat.type === 'chat' && rootScope.myId !== this.peerId && !(await this.managers.appNotificationsManager.isPeerLocalMuted({peerId: this.peerId, respectType: false, threadId: this.chat.threadId}))\n }, {\n icon: 'unmute',\n text: 'ChatList.Context.Unmute',\n onClick: () => {\n this.managers.appMessagesManager.togglePeerMute({peerId: this.peerId, threadId: this.chat.threadId});\n },\n verify: async() => this.chat.type === 'chat' && rootScope.myId !== this.peerId && (await this.managers.appNotificationsManager.isPeerLocalMuted({peerId: this.peerId, respectType: false, threadId: this.chat.threadId}))\n }, {\n icon: 'comments',\n text: 'ViewDiscussion',\n onClick: () => {\n const middleware = this.chat.bubbles.getMiddleware();\n Promise.resolve(this.managers.appProfileManager.getChannelFull(this.peerId.toChatId())).then((channelFull) => {\n if(middleware() && channelFull.linked_chat_id) {\n this.chat.appImManager.setInnerPeer({\n peerId: channelFull.linked_chat_id.toPeerId(true)\n });\n }\n });\n },\n verify: async() => {\n const chatFull = await this.managers.appProfileManager.getCachedFullChat(this.peerId.toChatId());\n return this.chat.type === 'chat' && !!(chatFull as ChatFull.channelFull)?.linked_chat_id;\n }\n }, {\n icon: 'phone',\n text: 'Call',\n onClick: this.onCallClick.bind(this, 'voice'),\n verify: this.verifyCallButton.bind(this, 'voice')\n }, {\n icon: 'videocamera',\n text: 'VideoCall',\n onClick: this.onCallClick.bind(this, 'video'),\n verify: this.verifyCallButton.bind(this, 'video')\n }, {\n icon: 'videochat',\n text: 'PeerInfo.Action.LiveStream',\n onClick: this.onJoinGroupCallClick,\n verify: this.verifyVideoChatButton.bind(this, 'broadcast')\n }, {\n icon: 'videochat',\n text: 'PeerInfo.Action.VoiceChat',\n onClick: this.onJoinGroupCallClick,\n verify: this.verifyVideoChatButton.bind(this, 'group')\n }, {\n icon: 'select',\n text: 'Chat.Menu.SelectMessages',\n onClick: () => {\n const selection = this.chat.selection;\n selection.toggleSelection(true, true);\n apiManagerProxy.getState().then((state) => {\n if(state.chatContextMenuHintWasShown) {\n return;\n }\n\n const original = selection.toggleByElement.bind(selection);\n selection.toggleByElement = async(bubble) => {\n this.managers.appStateManager.pushToState('chatContextMenuHintWasShown', true);\n toast(i18n('Chat.Menu.Hint'));\n\n selection.toggleByElement = original;\n selection.toggleByElement(bubble);\n };\n });\n },\n verify: () => !this.chat.selection.isSelecting && !!this.chat.bubbles.getRenderedLength()\n }, {\n icon: 'select',\n text: 'Chat.Menu.ClearSelection',\n onClick: () => {\n this.chat.selection.cancelSelection();\n },\n verify: () => this.chat.selection.isSelecting\n }, {\n icon: 'adduser',\n text: 'AddContact',\n onClick: () => {\n if(!this.appSidebarRight.isTabExists(AppEditContactTab)) {\n const tab = this.appSidebarRight.createTab(AppEditContactTab);\n tab.peerId = this.peerId;\n tab.open();\n\n this.appSidebarRight.toggleSidebar(true);\n }\n },\n verify: async() => this.peerId.isUser() && !(await this.managers.appPeersManager.isContact(this.peerId))\n }, {\n icon: 'forward',\n text: 'ShareContact',\n onClick: () => {\n const contactPeerId = this.peerId;\n PopupElement.createPopup(PopupPickUser, {\n peerTypes: ['dialogs', 'contacts'],\n onSelect: (peerId) => {\n return new Promise((resolve, reject) => {\n PopupElement.createPopup(PopupPeer, '', {\n titleLangKey: 'SendMessageTitle',\n descriptionLangKey: 'SendContactToGroupText',\n descriptionLangArgs: [new PeerTitle({peerId, dialog: true}).element],\n buttons: [{\n langKey: 'Send',\n callback: () => {\n resolve();\n\n this.managers.appMessagesManager.sendContact(peerId, contactPeerId);\n this.chat.appImManager.setInnerPeer({peerId});\n }\n }, {\n langKey: 'Cancel',\n callback: () => {\n reject();\n },\n isCancel: true\n }],\n peerId,\n overlayClosable: true\n }).show();\n });\n },\n placeholder: 'ShareModal.Search.Placeholder',\n chatRightsActions: ['send_plain'],\n selfPresence: 'ChatYourSelf'\n });\n },\n verify: async() => rootScope.myId !== this.peerId && this.peerId.isUser() && (await this.managers.appPeersManager.isContact(this.peerId)) && !!(await this.managers.appUsersManager.getUser(this.peerId.toUserId())).phone\n }, {\n icon: 'gift',\n text: 'GiftPremium',\n onClick: () => this.chat.appImManager.giftPremium(this.peerId),\n verify: () => this.chat.canGiftPremium()\n }, {\n icon: 'bots',\n text: 'Settings',\n onClick: () => {\n this.managers.appMessagesManager.sendText(this.peerId, '/settings');\n },\n verify: async() => {\n try {\n const attachMenuBot = await this.managers.appAttachMenuBotsManager.getAttachMenuBot(this.peerId.toUserId());\n return !!attachMenuBot?.pFlags?.has_settings;\n } catch(err) {\n return false;\n }\n }\n }, {\n icon: 'lock',\n text: 'BlockUser',\n onClick: () => {\n PopupElement.createPopup(PopupPeer, '', {\n peerId: this.peerId,\n titleLangKey: 'BlockUser',\n descriptionLangKey: 'AreYouSureBlockContact2',\n descriptionLangArgs: [new PeerTitle({peerId: this.peerId}).element],\n buttons: [{\n langKey: 'BlockUser',\n isDanger: true,\n callback: () => {\n this.managers.appUsersManager.toggleBlock(this.peerId, true).then((value) => {\n if(value) {\n toastNew({langPackKey: 'UserBlocked'});\n }\n });\n }\n }]\n }).show();\n },\n verify: async() => {\n if(!this.peerId.isUser()) return false;\n const userFull = await this.managers.appProfileManager.getCachedFullUser(this.peerId.toUserId());\n return this.peerId !== rootScope.myId && userFull && !userFull.pFlags?.blocked;\n }\n }, {\n icon: 'lockoff',\n text: 'Unblock',\n onClick: () => {\n this.managers.appUsersManager.toggleBlock(this.peerId, false).then((value) => {\n if(value) {\n toastNew({langPackKey: 'UserUnblocked'});\n }\n });\n },\n verify: async() => {\n const userFull = await this.managers.appProfileManager.getCachedFullUser(this.peerId.toUserId());\n return !!userFull?.pFlags?.blocked;\n }\n }, {\n icon: 'delete danger',\n text: 'Delete',\n onClick: () => {\n PopupElement.createPopup(PopupDeleteDialog, this.peerId/* , 'leave' */);\n },\n verify: async() => this.chat.type === 'chat' && !!(await this.managers.appMessagesManager.getDialogOnly(this.peerId))\n }];\n\n this.btnSearch = ButtonIcon('search');\n this.attachClickEvent(this.btnSearch, (e) => {\n this.chat.initSearch();\n }, true);\n }\n\n public attachClickEvent(el: HTMLElement, cb: (e: MouseEvent) => void, noBlur?: boolean) {\n attachClickEvent(el, (e) => {\n cancelEvent(e);\n !noBlur && blurActiveElement();\n cb(e);\n }, {listenerSetter: this.listenerSetter});\n }\n\n private onCallClick(type: CallType) {\n this.chat.appImManager.callUser(this.peerId.toUserId(), type);\n }\n\n private onJoinGroupCallClick = () => {\n this.chat.appImManager.joinGroupCall(this.peerId);\n };\n\n private constructAvatar() {\n const avatarElement = new AvatarElement();\n avatarElement.isDialog = true;\n avatarElement.classList.add('avatar-42', 'person-avatar');\n return avatarElement;\n }\n\n private get peerId() {\n return this.chat.peerId;\n }\n\n public constructPeerHelpers() {\n this.avatarElement = this.constructAvatar();\n\n this.subtitle = document.createElement('div');\n this.subtitle.classList.add('info');\n\n this.pinnedMessage = new ChatPinnedMessage(this, this.chat, this.managers);\n\n this.btnJoin = Button('btn-primary btn-color-primary chat-join hide');\n this.btnCall = ButtonIcon('phone');\n this.btnGroupCall = ButtonIcon('videochat');\n this.btnPinned = ButtonIcon('pinlist');\n this.btnMute = ButtonIcon('mute');\n\n this.attachClickEvent(this.btnCall, this.onCallClick.bind(this, 'voice'));\n this.attachClickEvent(this.btnGroupCall, this.onJoinGroupCallClick);\n\n this.attachClickEvent(this.btnPinned, () => {\n this.openPinned(true);\n });\n\n this.attachClickEvent(this.btnMute, this.onMuteClick);\n\n this.attachClickEvent(this.btnJoin, async() => {\n const middleware = this.chat.bubbles.getMiddleware();\n this.btnJoin.setAttribute('disabled', 'true');\n\n const chatId = this.peerId.toChatId();\n let promise: Promise<any>;\n if(await this.managers.appChatsManager.isChannel(chatId)) {\n promise = this.managers.appChatsManager.joinChannel(chatId);\n } else {\n promise = this.managers.appChatsManager.addChatUser(chatId, rootScope.myId);\n }\n\n promise.finally(() => {\n if(!middleware()) {\n return;\n }\n\n this.btnJoin.removeAttribute('disabled');\n });\n });\n\n this.listenerSetter.add(rootScope)('folder_unread', (folder) => {\n if(folder.id !== FOLDER_ID_ALL) {\n return;\n }\n\n const size = folder.unreadUnmutedPeerIds.size;\n this.btnBackBadge.textContent = size ? '' + formatNumber(size, 1) : '';\n // this.btnBack.classList.remove('tgico-left', 'tgico-previous');\n // this.btnBack.classList.add(size ? 'tgico-previous' : 'tgico-left');\n });\n\n this.listenerSetter.add(rootScope)('chat_update', async(chatId) => {\n if(this.peerId === chatId.toPeerId(true)) {\n const chat = await this.managers.appChatsManager.getChat(chatId) as Channel/* | Chat */;\n\n this.btnJoin.classList.toggle('hide', !(chat as Channel)?.pFlags?.left);\n this.setUtilsWidth();\n this.verifyButtons();\n }\n });\n\n this.listenerSetter.add(rootScope)('dialog_notify_settings', (dialog) => {\n if(dialog.peerId === this.peerId) {\n this.setMutedState();\n }\n });\n\n this.listenerSetter.add(rootScope)('peer_typings', ({peerId}) => {\n if(this.peerId === peerId) {\n this.setPeerStatus();\n }\n });\n\n this.listenerSetter.add(rootScope)('user_update', (userId) => {\n if(this.peerId === userId.toPeerId()) {\n this.setPeerStatus();\n }\n });\n\n this.listenerSetter.add(rootScope)('peer_full_update', (peerId) => {\n if(this.peerId === peerId) {\n this.verifyButtons();\n }\n });\n\n this.chat.addEventListener('setPeer', (mid, isTopMessage) => {\n const middleware = this.chat.bubbles.getMiddleware();\n apiManagerProxy.getState().then((state) => {\n if(!middleware() || !this.pinnedMessage) return;\n\n this.pinnedMessage.hidden = !!state.hiddenPinnedMessages[this.chat.peerId];\n\n if(isTopMessage) {\n this.pinnedMessage.unsetScrollDownListener();\n this.pinnedMessage.testMid(mid, 0); // * because slider will not let get bubble by document.elementFromPoint\n } else if(!this.pinnedMessage.locked) {\n this.pinnedMessage.handleFollowingPinnedMessage();\n this.pinnedMessage.testMid(mid);\n }\n });\n });\n\n this.listenerSetter.add(rootScope)('peer_pinned_messages', ({peerId, mids}) => {\n if(this.chat.type !== 'pinned' || peerId !== this.peerId) {\n return;\n }\n\n if(mids) {\n this.setTitle();\n }\n });\n\n this.setPeerStatusInterval = window.setInterval(this.setPeerStatus, 60e3);\n\n return this;\n }\n\n public openPinned(byCurrent: boolean) {\n this.chat.appImManager.setInnerPeer({\n peerId: this.peerId,\n lastMsgId: byCurrent ? +this.pinnedMessage.pinnedMessageContainer.divAndCaption.container.dataset.mid : 0,\n type: 'pinned'\n });\n }\n\n private onMuteClick = () => {\n PopupElement.createPopup(PopupMute, this.peerId);\n };\n\n private onResize = () => {\n this.setUtilsWidth(true);\n this.setFloating();\n };\n\n private onChangeScreen = (from: ScreenSize, to: ScreenSize) => {\n this.container.classList.toggle('is-pinned-floating', mediaSizes.isMobile);\n // this.chatAudio && this.chatAudio.divAndCaption.container.classList.toggle('is-floating', to === ScreenSize.mobile);\n this.pinnedMessage && this.pinnedMessage.pinnedMessageContainer.divAndCaption.container.classList.toggle('is-floating', to === ScreenSize.mobile);\n this.onResize();\n };\n\n public destroy() {\n // this.chat.log.error('Topbar destroying');\n this.listenerSetter.removeAll();\n window.clearInterval(this.setPeerStatusInterval);\n\n this.pinnedMessage?.destroy(); // * возможно это можно не делать\n this.chatAudio?.destroy();\n\n delete this.chatAudio;\n delete this.pinnedMessage;\n }\n\n public cleanup() {\n if(!this.chat.peerId) {\n this.container.classList.add('hide');\n }\n }\n\n public async finishPeerChange(options: Parameters<Chat['finishPeerChange']>[0]) {\n const {peerId, threadId} = this.chat;\n\n let newAvatar: AvatarElement;\n if(this.chat.type === 'chat') {\n if(this.avatarElement?.peerId !== this.peerId || this.avatarElement.threadId !== this.chat.threadId) {\n newAvatar = this.constructAvatar();\n } else {\n newAvatar = this.avatarElement;\n }\n }\n\n const [\n isBroadcast,\n isAnyChat,\n chat,\n _,\n setTitleCallback,\n setStatusCallback,\n state\n ] = await Promise.all([\n this.managers.appPeersManager.isBroadcast(peerId),\n this.managers.appPeersManager.isAnyChat(peerId),\n peerId.isAnyChat() ? this.managers.appChatsManager.getChat(peerId.toChatId()) : undefined,\n newAvatar ? newAvatar.updateWithOptions({peerId, threadId, wrapOptions: {customEmojiSize: makeMediaSize(32, 32)}}) : undefined,\n this.setTitleManual(),\n this.setPeerStatusManual(true),\n apiManagerProxy.getState()\n ]);\n\n return () => {\n const canHaveSomeButtons = !(this.chat.type === 'pinned' || this.chat.type === 'scheduled');\n this.btnMute && this.btnMute.classList.toggle('hide', !isBroadcast || !canHaveSomeButtons);\n if(this.btnJoin) {\n if(isAnyChat && !this.chat.isRestricted && canHaveSomeButtons) {\n replaceContent(this.btnJoin, i18n(isBroadcast ? 'Chat.Subscribe' : 'ChannelJoin'));\n this.btnJoin.classList.toggle('hide', !(chat as MTChat.chat)?.pFlags?.left);\n } else {\n this.btnJoin.classList.add('hide');\n }\n }\n\n if(this.btnSearch) {\n this.btnSearch.classList.toggle('hide', !canHaveSomeButtons);\n }\n\n if(this.btnPinned) {\n this.btnPinned.classList.toggle('hide', !canHaveSomeButtons);\n }\n\n if(this.avatarElement !== newAvatar) {\n if(newAvatar) {\n if(this.avatarElement) {\n this.avatarElement.replaceWith(newAvatar);\n } else {\n this.person.prepend(newAvatar);\n }\n }\n\n this.avatarElement?.remove();\n this.avatarElement = newAvatar;\n }\n\n this.setUtilsWidth();\n\n this.verifyButtons();\n\n if(this.btnMore) {\n this.btnMore.classList.toggle('hide', !canHaveSomeButtons);\n }\n\n const isPinnedMessagesNeeded = this.chat.isPinnedMessagesNeeded();\n if(isPinnedMessagesNeeded || this.chat.type === 'discussion') {\n if(this.chat.wasAlreadyUsed || !this.pinnedMessage) { // * change\n const newPinnedMessage = new ChatPinnedMessage(this, this.chat, this.managers);\n if(this.pinnedMessage) {\n this.pinnedMessage.pinnedMessageContainer.divAndCaption.container.replaceWith(newPinnedMessage.pinnedMessageContainer.divAndCaption.container);\n this.pinnedMessage.destroy();\n // this.pinnedMessage.pinnedMessageContainer.toggle(true);\n } else {\n this.chatUtils.prepend(this.pinnedMessage.pinnedMessageContainer.divAndCaption.container);\n }\n\n this.pinnedMessage = newPinnedMessage;\n }\n\n if(isPinnedMessagesNeeded) {\n this.pinnedMessage.hidden = !!state.hiddenPinnedMessages[peerId];\n } else if(this.chat.type === 'discussion') {\n this.pinnedMessage.pinnedMid = this.chat.threadId;\n this.pinnedMessage.count = 1;\n this.pinnedMessage.pinnedIndex = 0;\n this.pinnedMessage._setPinnedMessage();\n }\n } else if(this.pinnedMessage) {\n this.pinnedMessage.destroy();\n this.pinnedMessage = undefined;\n }\n\n setTitleCallback();\n setStatusCallback?.();\n this.subtitle.classList.toggle('hide', !setStatusCallback);\n this.setMutedState();\n\n this.container.classList.remove('hide');\n };\n }\n\n public async setTitleManual(count?: number) {\n const {peerId, threadId} = this.chat;\n const middleware = () => this.chat.bubbles.getMiddleware();\n let titleEl: HTMLElement, icons: Element[];\n if(this.chat.type === 'pinned') {\n if(count === undefined) titleEl = i18n('Loading');\n else titleEl = i18n('PinnedMessagesCount', [count]);\n\n if(count === undefined) {\n this.managers.appMessagesManager.getSearchCounters(peerId, [{_: 'inputMessagesFilterPinned'}], false).then((result) => {\n if(!middleware()) return;\n const count = result[0].count;\n this.setTitle(count);\n\n // ! костыль х2, это нужно делать в другом месте\n if(!count) {\n this.chat.appImManager.setPeer(); // * close tab\n\n // ! костыль, это скроет закреплённые сообщения сразу, вместо того, чтобы ждать пока анимация перехода закончится\n const originalChat = this.chat.appImManager.chat;\n if(originalChat.topbar.pinnedMessage) {\n originalChat.topbar.pinnedMessage.pinnedMessageContainer.toggle(true);\n }\n }\n });\n }\n } else if(this.chat.type === 'scheduled') {\n titleEl = i18n(peerId === rootScope.myId ? 'Reminders' : 'ScheduledMessages');\n } else if(this.chat.type === 'discussion') {\n if(count === undefined) {\n const result = await this.managers.acknowledged.appMessagesManager.getHistory(peerId, 0, 1, 0, threadId);\n if(!middleware()) return;\n if(result.cached) {\n const historyResult = await result.result;\n if(!middleware()) return;\n count = historyResult.count;\n } else result.result.then((historyResult) => {\n if(!middleware()) return;\n this.setTitle(historyResult.count);\n });\n }\n\n if(count === undefined) titleEl = i18n('Loading');\n else titleEl = i18n('Chat.Title.Comments', [count]);\n } else if(this.chat.type === 'chat') {\n [titleEl/* , icons */] = await Promise.all([\n wrapPeerTitle({\n peerId,\n dialog: true,\n withIcons: !threadId,\n threadId: threadId\n })\n // generateTitleIcons(peerId)\n ]);\n\n if(!middleware()) {\n return;\n }\n }\n\n return () => {\n replaceContent(this.title, titleEl);\n // if(icons) {\n // this.title.append(...icons);\n // }\n };\n }\n\n public setTitle(count?: number) {\n this.setTitleManual(count).then((setTitleCallback) => setTitleCallback());\n }\n\n public async setMutedState() {\n if(!this.btnMute) return;\n\n const peerId = this.peerId;\n const muted = await this.managers.appNotificationsManager.isPeerLocalMuted({peerId, respectType: false, threadId: this.chat.threadId});\n if(await this.managers.appPeersManager.isBroadcast(peerId)) { // not human\n this.btnMute.classList.remove('tgico-mute', 'tgico-unmute');\n this.btnMute.classList.add(muted ? 'tgico-unmute' : 'tgico-mute');\n this.btnMute.style.display = '';\n } else {\n this.btnMute.style.display = 'none';\n }\n }\n\n // ! У МЕНЯ ПРОСТО СГОРЕЛО, САФАРИ КОНЧЕННЫЙ БРАУЗЕР - ЕСЛИ НЕ СКРЫВАТЬ БЛОК, ТО ПРИ ПЕРЕВОРОТЕ ЭКРАНА НА АЙФОНЕ БЛОК БУДЕТ НЕПРАВИЛЬНО ШИРИНЫ, ДАЖЕ БЕЗ ЭТОЙ ФУНКЦИИ!\n public setUtilsWidth = (resize = false) => {\n // return;\n if(this.setUtilsRAF) window.cancelAnimationFrame(this.setUtilsRAF);\n\n if(IS_SAFARI && resize) {\n this.chatUtils.classList.add('hide');\n }\n\n // mutationObserver.disconnect();\n this.setUtilsRAF = window.requestAnimationFrame(() => {\n // mutationRAF = window.requestAnimationFrame(() => {\n\n // setTimeout(() => {\n if(IS_SAFARI && resize) {\n this.chatUtils.classList.remove('hide');\n }\n /* this.chatInfo.style.removeProperty('--utils-width');\n void this.chatInfo.offsetLeft; // reflow */\n const width = /* chatUtils.scrollWidth */this.chatUtils.getBoundingClientRect().width;\n this.chat.log('utils width:', width);\n this.container.style.setProperty('--utils-width', width + 'px');\n // this.chatInfo.classList.toggle('have-utils-width', !!width);\n // }, 0);\n\n this.setUtilsRAF = 0;\n\n // mutationObserver.observe(chatUtils, observeOptions);\n // });\n });\n };\n\n public setFloating = () => {\n const containers = [this.chatAudio, this.pinnedMessage?.pinnedMessageContainer].filter(Boolean);\n const count = containers.reduce((acc, container) => {\n const isFloating = container.isFloating();\n this.container.classList.toggle(`is-pinned-${container.className}-floating`, isFloating);\n\n if(!container.isVisible()) {\n return acc;\n }\n\n return acc + +isFloating;\n }, 0);\n this.container.dataset.floating = '' + count;\n };\n\n public setPeerStatusManual = async(needClear = false) => {\n if(!this.subtitle || this.chat.type !== 'chat') return;\n\n if(this.chat.threadId) {\n const title = await wrapPeerTitle({peerId: this.peerId, dialog: true});\n const span = i18n('TopicProfileStatus', [title]);\n return () => replaceContent(this.subtitle, span);\n }\n\n const peerId = this.peerId;\n return this.chat.appImManager.setPeerStatus({\n peerId,\n element: this.subtitle,\n needClear,\n useWhitespace: false,\n middleware: () => peerId === this.peerId\n });\n };\n\n public setPeerStatus = (needClear?: boolean) => {\n return this.setPeerStatusManual(needClear).then((callback) => {\n callback?.();\n });\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport appSidebarRight from '..';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport AppSearch, {SearchGroup} from '../../appSearch';\nimport ButtonIcon from '../../buttonIcon';\nimport InputSearch from '../../inputSearch';\nimport PopupElement from '../../popups';\nimport PopupDatePicker from '../../popups/datePicker';\nimport {SliderSuperTab} from '../../slider';\n\nexport default class AppPrivateSearchTab extends SliderSuperTab {\n private inputSearch: InputSearch;\n private appSearch: AppSearch;\n private btnPickDate: HTMLElement;\n\n private peerId: PeerId;\n private threadId = 0;\n private query = '';\n private onDatePick: (timestamp: number) => void;\n\n onOpenAfterTimeout() {\n this.appSearch.beginSearch(this.peerId, this.threadId, this.query);\n }\n\n public init(\n peerId: PeerId,\n threadId?: number,\n onDatePick?: AppPrivateSearchTab['onDatePick'],\n query?: string\n ) {\n this.container.id = 'search-private-container';\n this.container.classList.add('chatlist-container');\n this.inputSearch = new InputSearch('Search');\n this.title.replaceWith(this.inputSearch.container);\n\n this.btnPickDate = ButtonIcon('calendar sidebar-header-right');\n this.header.append(this.btnPickDate);\n\n const c = document.createElement('div');\n c.classList.add('chatlist-container');\n this.scrollable.container.replaceWith(c);\n this.appSearch = new AppSearch(c, this.inputSearch, {\n messages: new SearchGroup('Chat.Search.PrivateSearch', 'messages')\n });\n\n if(!this.peerId) {\n this.query = query;\n this.peerId = peerId;\n this.threadId = threadId;\n this.onDatePick = onDatePick;\n\n this.btnPickDate.classList.toggle('hide', !this.onDatePick);\n if(this.onDatePick) {\n attachClickEvent(this.btnPickDate, () => {\n PopupElement.createPopup(PopupDatePicker, new Date(), this.onDatePick).show();\n });\n }\n\n query && this.appSearch.searchInput.inputField.setValueSilently(query);\n\n appSidebarRight.toggleSidebar(true);\n } else {\n this.appSearch.beginSearch(this.peerId, this.threadId, query);\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type ChatTopbar from './topbar';\nimport AppSearch, {SearchGroup} from '../appSearch';\nimport PopupDatePicker from '../popups/datePicker';\nimport ripple from '../ripple';\nimport InputSearch from '../inputSearch';\nimport type Chat from './chat';\nimport findUpTag from '../../helpers/dom/findUpTag';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport whichChild from '../../helpers/dom/whichChild';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport {i18n} from '../../lib/langPack';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport appNavigationController, {NavigationItem} from '../appNavigationController';\nimport {IS_MOBILE_SAFARI} from '../../environment/userAgent';\nimport PopupElement from '../popups';\nimport {DIALOG_LIST_ELEMENT_TAG} from '../../lib/appManagers/appDialogsManager';\n\nexport default class ChatSearch {\n private element: HTMLElement;\n private backBtn: HTMLElement;\n private inputSearch: InputSearch;\n\n private results: HTMLElement;\n\n private footer: HTMLElement;\n private dateBtn: HTMLElement;\n private foundCountEl: HTMLElement;\n private controls: HTMLElement;\n private downBtn: HTMLElement;\n private upBtn: HTMLElement;\n\n private appSearch: AppSearch;\n private searchGroup: SearchGroup;\n\n private foundCount = 0;\n private selectedIndex = 0;\n private setPeerPromise: Promise<any>;\n private listenerSetter: ListenerSetter;\n private navigationItem: NavigationItem;\n\n constructor(private topbar: ChatTopbar, private chat: Chat, query?: string) {\n this.element = document.createElement('div');\n this.element.classList.add('sidebar-header', 'chat-search', 'chatlist-container');\n\n this.backBtn = document.createElement('button');\n this.backBtn.classList.add('btn-icon', 'tgico-left', 'sidebar-close-button');\n ripple(this.backBtn);\n\n const listenerSetter = this.listenerSetter = new ListenerSetter();\n\n const attachClick = (element: HTMLElement, callback: (e: MouseEvent) => void) => {\n attachClickEvent(element, callback, {listenerSetter});\n };\n\n attachClick(this.backBtn, () => {\n this.destroy();\n });\n\n this.inputSearch = new InputSearch('Search');\n\n // Results\n this.results = document.createElement('div');\n this.results.classList.add('chat-search-results', 'chatlist-container');\n\n this.searchGroup = new SearchGroup(false, 'messages', undefined, '', false);\n attachClick(this.searchGroup.list, this.onResultsClick);\n\n this.appSearch = new AppSearch(this.results, this.inputSearch, {\n messages: this.searchGroup\n }, (count) => {\n this.foundCount = count;\n\n if(!this.foundCount) {\n replaceContent(this.foundCountEl, this.inputSearch.value ? i18n('NoResult') : '');\n this.results.classList.remove('active');\n this.chat.bubbles.container.classList.remove('search-results-active');\n this.upBtn.setAttribute('disabled', 'true');\n this.downBtn.setAttribute('disabled', 'true');\n } else {\n this.selectResult(this.searchGroup.list.children[0] as HTMLElement);\n }\n });\n this.appSearch.beginSearch(this.chat.peerId, this.chat.threadId);\n\n // appImManager.topbar.parentElement.insertBefore(this.results, appImManager.bubblesContainer);\n this.chat.bubbles.container.append(this.results);\n\n // Footer\n this.footer = document.createElement('div');\n this.footer.classList.add('chat-search-footer');\n\n attachClick(this.footer, this.onFooterClick);\n ripple(this.footer);\n\n this.foundCountEl = document.createElement('span');\n this.foundCountEl.classList.add('chat-search-count');\n\n this.dateBtn = document.createElement('button');\n this.dateBtn.classList.add('btn-icon', 'tgico-calendar');\n\n this.controls = document.createElement('div');\n this.controls.classList.add('chat-search-controls');\n\n this.upBtn = document.createElement('button');\n this.upBtn.classList.add('btn-icon', 'tgico-up');\n this.downBtn = document.createElement('button');\n this.downBtn.classList.add('btn-icon', 'tgico-down');\n\n this.upBtn.setAttribute('disabled', 'true');\n this.downBtn.setAttribute('disabled', 'true');\n\n attachClick(this.dateBtn, this.onDateClick);\n attachClick(this.upBtn, this.onUpClick);\n attachClick(this.downBtn, this.onDownClick);\n this.controls.append(this.upBtn, this.downBtn);\n\n this.footer.append(this.foundCountEl, this.dateBtn, this.controls);\n\n this.topbar.container.parentElement.insertBefore(this.footer, chat.input.chatInput);\n\n // Append container\n this.element.append(this.backBtn, this.inputSearch.container);\n\n this.topbar.container.classList.add('hide-pinned');\n this.topbar.container.parentElement.append(this.element);\n\n this.inputSearch.input.focus();\n\n if(query) {\n this.setQuery(query);\n }\n\n if(!IS_MOBILE_SAFARI) {\n this.navigationItem = {\n type: 'mobile-search',\n onPop: () => {\n this.destroy();\n }\n };\n\n appNavigationController.pushItem(this.navigationItem);\n }\n }\n\n public destroy() {\n this.topbar.container.classList.remove('hide-pinned');\n this.element.remove();\n this.inputSearch.remove();\n this.results.remove();\n this.footer.remove();\n this.listenerSetter.removeAll();\n this.chat.bubbles.container.classList.remove('search-results-active');\n this.chat.search = undefined;\n appNavigationController.removeItem(this.navigationItem);\n }\n\n public setQuery(query: string) {\n this.inputSearch.inputField.value = query;\n }\n\n private onDateClick = (e: MouseEvent) => {\n cancelEvent(e);\n PopupElement.createPopup(PopupDatePicker, new Date(), this.chat.bubbles.onDatePick).show();\n };\n\n private selectResult(elem: HTMLElement) {\n if(this.setPeerPromise) return this.setPeerPromise;\n\n const peerId = elem.dataset.peerId.toPeerId();\n const lastMsgId = +elem.dataset.mid || undefined;\n\n const index = whichChild(elem);\n\n if(index === (this.foundCount - 1)) {\n this.upBtn.setAttribute('disabled', 'true');\n } else {\n this.upBtn.removeAttribute('disabled');\n }\n\n if(!index) {\n this.downBtn.setAttribute('disabled', 'true');\n } else {\n this.downBtn.removeAttribute('disabled');\n }\n\n this.results.classList.remove('active');\n this.chat.bubbles.container.classList.remove('search-results-active');\n\n const res = this.chat.setPeer({peerId, lastMsgId});\n this.setPeerPromise = ((res instanceof Promise ? res : Promise.resolve(res)) as Promise<any>).then(() => {\n this.selectedIndex = index;\n replaceContent(this.foundCountEl, i18n('Of', [index + 1, this.foundCount]));\n\n const renderedCount = this.searchGroup.list.childElementCount;\n if(this.selectedIndex >= (renderedCount - 6)) {\n this.appSearch.searchMore();\n }\n }).finally(() => {\n this.setPeerPromise = null;\n });\n }\n\n private onResultsClick = (e: MouseEvent) => {\n const target = findUpTag(e.target, DIALOG_LIST_ELEMENT_TAG);\n if(target) {\n this.selectResult(target);\n }\n };\n\n private onFooterClick = (e: MouseEvent) => {\n if(this.foundCount) {\n this.chat.bubbles.container.classList.toggle('search-results-active');\n this.results.classList.toggle('active');\n }\n };\n\n private onUpClick = (e: MouseEvent) => {\n cancelEvent(e);\n this.selectResult(this.searchGroup.list.children[this.selectedIndex + 1] as HTMLElement);\n };\n\n private onDownClick = (e: MouseEvent) => {\n cancelEvent(e);\n this.selectResult(this.searchGroup.list.children[this.selectedIndex - 1] as HTMLElement);\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport deepEqual from '../../helpers/object/deepEqual';\nimport {renderImageFromUrlPromise} from '../../helpers/dom/renderImageFromUrl';\nimport mediaSizes, {ScreenSize} from '../../helpers/mediaSizes';\nimport windowSize from '../../helpers/windowSize';\nimport IS_IMAGE_BITMAP_SUPPORTED from '../../environment/imageBitmapSupport';\n\ntype ChatBackgroundPatternRendererInitOptions = {\n url: string,\n width: number,\n height: number,\n mask?: boolean\n};\n\nexport default class ChatBackgroundPatternRenderer {\n private static INSTANCES: ChatBackgroundPatternRenderer[] = [];\n\n // private pattern: CanvasPattern;\n private objectUrl: string;\n private options: ChatBackgroundPatternRendererInitOptions;\n private canvases: Set<HTMLCanvasElement>;\n // private createCanvasPatternPromise: Promise<CanvasPattern>;\n // private exportCanvasPatternToImagePromise: Promise<string>;\n private renderImageFromUrlPromise: Promise<HTMLImageElement>;\n private image: HTMLImageElement;\n private imageBitmap: ImageBitmap;\n\n constructor() {\n this.canvases = new Set();\n }\n\n public static getInstance(options: ChatBackgroundPatternRendererInitOptions) {\n let instance = this.INSTANCES.find((instance) => {\n return deepEqual(instance.options, options);\n });\n\n if(!instance) {\n instance = new ChatBackgroundPatternRenderer();\n instance.init(options);\n this.INSTANCES.push(instance);\n }\n\n return instance;\n }\n\n public init(options: ChatBackgroundPatternRendererInitOptions) {\n // if(this.options) {\n // if(this.options.width !== options.width || this.options.height !== options.height) {\n // this.createCanvasPatternPromise =\n // this.pattern =\n // this.exportCanvasPatternToImagePromise =\n // undefined;\n // }\n // }\n\n this.options = options;\n }\n\n public renderToCanvas(canvas: HTMLCanvasElement) {\n // return this.createCanvasPattern(canvas).then(() => {\n // return this.fillCanvas(canvas);\n // });\n\n return this.renderImageFromUrl(this.options.url).then(() => {\n return this.fillCanvas(canvas);\n });\n }\n\n private renderImageFromUrl(url: string) {\n if(this.renderImageFromUrlPromise) return this.renderImageFromUrlPromise;\n const img = this.image = document.createElement('img');\n img.crossOrigin = 'anonymous';\n return this.renderImageFromUrlPromise = renderImageFromUrlPromise(img, url, false).then(() => {\n if(!IS_IMAGE_BITMAP_SUPPORTED) {\n return img;\n }\n\n return createImageBitmap(img, {\n resizeWidth: 1440,\n resizeHeight: 2960\n }).then((imageBitmap) => {\n this.imageBitmap = imageBitmap;\n return img;\n });\n });\n }\n\n /* private createCanvasPattern(canvas: HTMLCanvasElement) {\n if(this.createCanvasPatternPromise) return this.createCanvasPatternPromise;\n return this.createCanvasPatternPromise = this.renderImageFromUrl(this.options.url).then((img) => {\n let createPatternFrom: HTMLImageElement | HTMLCanvasElement;\n if(IS_SAFARI) {\n const canvas = createPatternFrom = document.createElement('canvas');\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n const ctx = canvas.getContext('2d');\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height);\n } else {\n createPatternFrom = img;\n }\n\n const perf = performance.now();\n this.pattern = canvas.getContext('2d').createPattern(createPatternFrom, 'repeat-x');\n console.warn('creating pattern time:', performance.now() - perf);\n\n return this.pattern;\n });\n }\n\n public exportCanvasPatternToImage(canvas: HTMLCanvasElement) {\n if(this.exportCanvasPatternToImagePromise) return this.exportCanvasPatternToImagePromise;\n return this.exportCanvasPatternToImagePromise = new Promise<string>((resolve) => {\n canvas.toBlob((blob) => {\n const newUrl = this.objectUrl = URL.createObjectURL(blob);\n resolve(newUrl);\n }, 'image/png');\n });\n } */\n\n public cleanup(canvas: HTMLCanvasElement) {\n this.canvases.delete(canvas);\n\n if(!this.canvases.size) {\n indexOfAndSplice(ChatBackgroundPatternRenderer.INSTANCES, this);\n\n if(this.objectUrl) {\n this.imageBitmap?.close();\n URL.revokeObjectURL(this.objectUrl);\n }\n }\n }\n\n public fillCanvas(canvas: HTMLCanvasElement) {\n const context = canvas.getContext('2d');\n const {width, height} = canvas;\n // const perf = performance.now();\n // if(context.fillStyle instanceof CanvasPattern) {\n // context.clearRect(0, 0, width, height);\n // }\n\n const source = this.imageBitmap || this.image;\n\n let imageWidth = source.width, imageHeight = source.height;\n // let patternHeight = 1480 * canvas.dpr;\n // if(+canvas.dataset.originalHeight !== height) patternHeight *= .6875;\n const patternHeight = (500 + (windowSize.height / 2.5)) * canvas.dpr;\n const ratio = patternHeight / imageHeight;\n imageWidth *= ratio;\n imageHeight = patternHeight;\n\n if(this.options.mask) {\n context.fillStyle = '#000';\n context.fillRect(0, 0, width, height);\n context.globalCompositeOperation = 'destination-out';\n } else {\n context.globalCompositeOperation = 'source-over';\n }\n\n const d = (y: number) => {\n for(let x = 0; x < width; x += imageWidth) {\n context.drawImage(source, x, y, imageWidth, imageHeight);\n }\n };\n\n const centerY = (height - imageHeight) / 2;\n d(centerY);\n\n if(centerY > 0) {\n let topY = centerY;\n do {\n d(topY -= imageHeight);\n } while(topY >= 0);\n }\n\n const endY = height - 1;\n for(let bottomY = centerY + imageHeight; bottomY < endY; bottomY += imageHeight) {\n d(bottomY);\n }\n\n // for(let x = 0; x < width; x += imageWidth) {\n // for(let y = 0; y < height; y += imageHeight) {\n // context.drawImage(img, x, y, imageWidth, imageHeight);\n // }\n // }\n // context.fillStyle = this.pattern;\n // context.fillRect(0, 0, width, height);\n // console.warn('fill canvas time', performance.now() - perf);\n }\n\n public setCanvasDimensions(canvas: HTMLCanvasElement) {\n const devicePixelRatio = Math.min(2, window.devicePixelRatio);\n const width = this.options.width * devicePixelRatio;\n let height = this.options.height * devicePixelRatio;\n\n canvas.dpr = devicePixelRatio;\n canvas.dataset.originalHeight = '' + height;\n if(mediaSizes.activeScreen === ScreenSize.large) height *= 1.5;\n canvas.width = width;\n canvas.height = height;\n }\n\n public createCanvas() {\n const canvas = document.createElement('canvas');\n this.canvases.add(canvas);\n this.setCanvasDimensions(canvas);\n return canvas;\n }\n\n public resize(width: number, height: number) {\n this.init({\n ...this.options,\n width,\n height\n });\n\n const promises: Promise<any>[] = [];\n for(const canvas of this.canvases) {\n this.setCanvasDimensions(canvas);\n promises.push(this.renderToCanvas(canvas));\n }\n\n return Promise.all(promises);\n }\n\n public static resizeInstances(width: number, height: number) {\n return Promise.all(this.INSTANCES.map((instance) => instance.resize(width, height)));\n }\n\n /* public setResizeMode(resizing: boolean) {\n const canvases = Array.from(this.canvases);\n const canvas = canvases[canvases.length - 1];\n canvas.style.display = resizing ? 'none' : '';\n const img = this.img;\n img.style.display = resizing ? '' : 'none';\n\n return {img, canvas};\n } */\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {ChatRights} from '../../lib/appManagers/appChatsManager';\nimport {AppImManager, APP_TABS, ChatSetPeerOptions} from '../../lib/appManagers/appImManager';\nimport type {MessageSendingParams, MessagesStorageKey} from '../../lib/appManagers/appMessagesManager';\nimport EventListenerBase from '../../helpers/eventListenerBase';\nimport {logger, LogTypes} from '../../lib/logger';\nimport rootScope from '../../lib/rootScope';\nimport appSidebarRight from '../sidebarRight';\nimport ChatBubbles from './bubbles';\nimport ChatContextMenu from './contextMenu';\nimport ChatInput from './input';\nimport ChatSelection from './selection';\nimport ChatTopbar from './topbar';\nimport {NULL_PEER_ID, REPLIES_PEER_ID} from '../../lib/mtproto/mtproto_config';\nimport SetTransition from '../singleTransition';\nimport AppPrivateSearchTab from '../sidebarRight/tabs/search';\nimport renderImageFromUrl from '../../helpers/dom/renderImageFromUrl';\nimport mediaSizes, {ScreenSize} from '../../helpers/mediaSizes';\nimport ChatSearch from './search';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport getAutoDownloadSettingsByPeerId, {ChatAutoDownloadSettings} from '../../helpers/autoDownload';\nimport ChatBackgroundGradientRenderer from './gradientRenderer';\nimport ChatBackgroundPatternRenderer from './patternRenderer';\nimport pause from '../../helpers/schedulers/pause';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport SlicedArray from '../../helpers/slicedArray';\nimport themeController from '../../helpers/themeController';\nimport AppSharedMediaTab from '../sidebarRight/tabs/sharedMedia';\nimport noop from '../../helpers/noop';\nimport middlewarePromise from '../../helpers/middlewarePromise';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport {Message, WallPaper} from '../../layer';\nimport animationIntersector, {AnimationItemGroup} from '../animationIntersector';\nimport {getColorsFromWallPaper} from '../../helpers/color';\nimport liteMode from '../../helpers/liteMode';\n\nexport type ChatType = 'chat' | 'pinned' | 'discussion' | 'scheduled';\n\nexport default class Chat extends EventListenerBase<{\n setPeer: (mid: number, isTopMessage: boolean) => void\n}> {\n public container: HTMLElement;\n public backgroundEl: HTMLElement;\n\n public topbar: ChatTopbar;\n public bubbles: ChatBubbles;\n public input: ChatInput;\n public selection: ChatSelection;\n public contextMenu: ChatContextMenu;\n public search: ChatSearch;\n\n public wasAlreadyUsed: boolean;\n // public initPeerId = 0;\n public peerId: PeerId;\n public threadId: number;\n public setPeerPromise: Promise<void>;\n public peerChanged: boolean;\n\n public log: ReturnType<typeof logger>;\n\n public type: ChatType;\n public messagesStorageKey: MessagesStorageKey;\n\n public noForwards: boolean;\n\n public inited: boolean;\n\n public isRestricted: boolean;\n public autoDownload: ChatAutoDownloadSettings;\n\n public gradientRenderer: ChatBackgroundGradientRenderer;\n public patternRenderer: ChatBackgroundPatternRenderer;\n public gradientCanvas: HTMLCanvasElement;\n public patternCanvas: HTMLCanvasElement;\n public backgroundTempId: number;\n public setBackgroundPromise: Promise<void>;\n public sharedMediaTab: AppSharedMediaTab;\n public sharedMediaTabs: AppSharedMediaTab[];\n // public renderDarkPattern: () => Promise<void>;\n\n public isBot: boolean;\n public isChannel: boolean;\n public isBroadcast: boolean;\n public isAnyGroup: boolean;\n public isMegagroup: boolean;\n public isForum: boolean;\n public isAllMessagesForum: boolean;\n public isAnonymousSending: boolean;\n\n public animationGroup: AnimationItemGroup;\n\n constructor(\n public appImManager: AppImManager,\n public managers: AppManagers\n ) {\n super();\n\n this.type = 'chat';\n this.animationGroup = `chat-${Math.round(Math.random() * 65535)}`;\n\n this.container = document.createElement('div');\n this.container.classList.add('chat', 'tabs-tab');\n\n this.backgroundEl = document.createElement('div');\n this.backgroundEl.classList.add('chat-background');\n\n // * constructor end\n\n this.log = logger('CHAT', LogTypes.Log | LogTypes.Warn | LogTypes.Debug | LogTypes.Error);\n this.log.warn('constructor');\n\n this.peerId = NULL_PEER_ID;\n\n this.container.append(this.backgroundEl);\n this.appImManager.chatsContainer.append(this.container);\n\n this.backgroundTempId = 0;\n this.sharedMediaTabs = [];\n }\n\n public setBackground(url: string, skipAnimation?: boolean): Promise<void> {\n const theme = themeController.getTheme();\n const themeSettings = theme.settings;\n const wallPaper = themeSettings.wallpaper;\n const colors = getColorsFromWallPaper(wallPaper);\n\n let item: HTMLElement;\n const isColorBackground = !!colors && !(wallPaper as WallPaper.wallPaper).slug && !wallPaper.settings.intensity;\n if(\n isColorBackground &&\n document.documentElement.style.cursor === 'grabbing' &&\n this.gradientRenderer &&\n !this.patternRenderer\n ) {\n this.gradientCanvas.dataset.colors = colors;\n this.gradientRenderer.init(this.gradientCanvas);\n return Promise.resolve();\n }\n\n const tempId = ++this.backgroundTempId;\n\n const previousGradientRenderer = this.gradientRenderer;\n const previousPatternRenderer = this.patternRenderer;\n const previousGradientCanvas = this.gradientCanvas;\n const previousPatternCanvas = this.patternCanvas;\n\n this.gradientRenderer =\n this.patternRenderer =\n this.gradientCanvas =\n this.patternCanvas =\n // this.renderDarkPattern =\n undefined;\n\n const intensity = wallPaper.settings?.intensity && wallPaper.settings.intensity / 100;\n const isDarkPattern = !!intensity && intensity < 0;\n\n let patternRenderer: ChatBackgroundPatternRenderer;\n let patternCanvas = item?.firstElementChild as HTMLCanvasElement;\n let gradientCanvas: HTMLCanvasElement;\n if(!item) {\n item = document.createElement('div');\n item.classList.add('chat-background-item');\n\n if(url) {\n if(intensity) {\n item.classList.add('is-pattern');\n\n const rect = this.appImManager.chatsContainer.getBoundingClientRect();\n patternRenderer = this.patternRenderer = ChatBackgroundPatternRenderer.getInstance({\n url,\n width: rect.width,\n height: rect.height,\n mask: isDarkPattern\n });\n\n patternCanvas = this.patternCanvas = patternRenderer.createCanvas();\n patternCanvas.classList.add('chat-background-item-canvas', 'chat-background-item-pattern-canvas');\n\n if(isDarkPattern) {\n item.classList.add('is-dark');\n }\n\n // if(isDarkPattern) {\n // this.renderDarkPattern = () => {\n // return patternRenderer.exportCanvasPatternToImage(patternCanvas).then((url) => {\n // if(this.backgroundTempId !== tempId) {\n // return;\n // }\n\n // gradientCanvas.style.webkitMaskImage = `url(${url})`;\n // });\n // };\n // }\n } else {\n item.classList.add('is-image');\n }\n } else {\n item.classList.add('is-color');\n }\n }\n\n let gradientRenderer: ChatBackgroundGradientRenderer;\n if(colors) {\n // if(color.includes(',')) {\n const {canvas, gradientRenderer: _gradientRenderer} = ChatBackgroundGradientRenderer.create(colors);\n gradientRenderer = this.gradientRenderer = _gradientRenderer;\n gradientCanvas = this.gradientCanvas = canvas;\n gradientCanvas.classList.add('chat-background-item-canvas', 'chat-background-item-color-canvas');\n\n if(liteMode.isAvailable('animations')) {\n gradientRenderer.scrollAnimate(true);\n }\n // } else {\n // item.style.backgroundColor = color;\n // item.style.backgroundImage = 'none';\n // }\n }\n\n if(patternRenderer) {\n const setOpacityTo = isDarkPattern ? gradientCanvas : patternCanvas;\n let opacityMax = Math.abs(intensity) * (isDarkPattern ? .5 : 1);\n if(isDarkPattern) {\n opacityMax = Math.max(0.3, opacityMax);\n }\n setOpacityTo.style.setProperty('--opacity-max', '' + opacityMax);\n }\n\n const promise = new Promise<void>((resolve) => {\n const cb = () => {\n if(this.backgroundTempId !== tempId) {\n if(patternRenderer) {\n patternRenderer.cleanup(patternCanvas);\n }\n\n if(gradientRenderer) {\n gradientRenderer.cleanup();\n }\n\n return;\n }\n\n const prev = this.backgroundEl.lastElementChild as HTMLElement;\n\n if(prev === item) {\n resolve();\n return;\n }\n\n const append = [\n gradientCanvas,\n // isDarkPattern && this.renderDarkPattern ? undefined : patternCanvas\n patternCanvas\n ].filter(Boolean);\n if(append.length) {\n item.append(...append);\n }\n\n this.backgroundEl.append(item);\n\n SetTransition({\n element: item,\n className: 'is-visible',\n forwards: true,\n duration: !skipAnimation ? 200 : 0,\n onTransitionEnd: prev ? () => {\n previousPatternRenderer?.cleanup(previousPatternCanvas);\n previousGradientRenderer?.cleanup();\n\n prev.remove();\n } : null,\n useRafs: 2\n });\n\n resolve();\n };\n\n if(patternRenderer) {\n const renderPatternPromise = patternRenderer.renderToCanvas(patternCanvas);\n renderPatternPromise.then(() => {\n if(this.backgroundTempId !== tempId) {\n return;\n }\n\n // let promise: Promise<any>;\n // if(isDarkPattern && this.renderDarkPattern) {\n // promise = this.renderDarkPattern();\n // } else {\n // const promise = Promise.resolve();\n // }\n\n // promise.then(cb);\n cb();\n });\n } else if(url) {\n renderImageFromUrl(item, url, cb);\n } else {\n cb();\n }\n });\n\n return this.setBackgroundPromise = Promise.race([\n pause(500),\n promise\n ]);\n }\n\n public setType(type: ChatType) {\n this.type = type;\n }\n\n public init(/* peerId: PeerId */) {\n // this.initPeerId = peerId;\n\n this.topbar = new ChatTopbar(this, appSidebarRight, this.managers);\n this.bubbles = new ChatBubbles(this, this.managers);\n this.input = new ChatInput(this, this.appImManager, this.managers);\n this.contextMenu = new ChatContextMenu(this, this.managers);\n this.selection = new ChatSelection(this, this.bubbles, this.input, this.managers);\n\n this.topbar.constructUtils();\n this.topbar.constructPeerHelpers();\n\n this.topbar.construct();\n this.input.construct();\n\n this.bubbles.constructPeerHelpers();\n this.input.constructPeerHelpers();\n\n if(!IS_TOUCH_SUPPORTED) {\n this.bubbles.setReactionsHoverListeners();\n }\n\n this.bubbles.attachContainerListeners();\n\n this.container.append(this.topbar.container, this.bubbles.container, this.input.chatInput);\n\n this.bubbles.listenerSetter.add(rootScope)('dialog_migrate', ({migrateFrom, migrateTo}) => {\n if(this.peerId === migrateFrom) {\n this.setPeer({peerId: migrateTo});\n }\n });\n\n this.bubbles.listenerSetter.add(rootScope)('dialog_drop', (dialog) => {\n if(dialog.peerId === this.peerId && (dialog._ === 'dialog' || this.threadId === dialog.id)) {\n this.appImManager.setPeer();\n }\n });\n\n this.bubbles.listenerSetter.add(rootScope)('chat_update', async(chatId) => {\n const {peerId} = this;\n if(peerId.isAnyChat() && peerId.toChatId() === chatId) {\n const isAnonymousSending = await this.managers.appMessagesManager.isAnonymousSending(peerId);\n if(peerId === this.peerId) {\n this.isAnonymousSending = isAnonymousSending;\n }\n }\n });\n\n const freezeObservers = (freeze: boolean) => {\n const cb = () => {\n this.bubbles.observer?.toggleObservingNew(freeze);\n animationIntersector.toggleIntersectionGroup(this.animationGroup, freeze);\n if(freeze) {\n animationIntersector.checkAnimations(freeze, this.animationGroup);\n }\n };\n\n if(!freeze) {\n setTimeout(() => {\n cb();\n }, 400);\n } else {\n cb();\n }\n };\n\n this.bubbles.listenerSetter.add(this.appImManager)('chat_changing', ({to}) => {\n freezeObservers(to !== this);\n });\n\n this.bubbles.listenerSetter.add(this.appImManager)('tab_changing', (tabId) => {\n freezeObservers(this.appImManager.chat !== this || (tabId !== APP_TABS.CHAT && mediaSizes.activeScreen === ScreenSize.mobile));\n });\n }\n\n public beforeDestroy() {\n this.bubbles.cleanup();\n }\n\n private cleanupBackground() {\n ++this.backgroundTempId;\n if(this.patternRenderer) {\n this.patternRenderer.cleanup(this.patternCanvas);\n this.patternRenderer = undefined;\n }\n\n if(this.gradientRenderer) {\n this.gradientRenderer.cleanup();\n this.gradientRenderer = undefined;\n }\n }\n\n public destroy() {\n // const perf = performance.now();\n\n this.destroySharedMediaTab();\n this.topbar.destroy();\n this.bubbles.destroy();\n this.input.destroy();\n this.contextMenu && this.contextMenu.destroy();\n this.selection && this.selection.attachListeners(undefined, undefined);\n\n this.cleanupBackground();\n\n delete this.topbar;\n delete this.bubbles;\n delete this.input;\n delete this.selection;\n delete this.contextMenu;\n\n this.container.remove();\n\n // this.log.error('Chat destroy time:', performance.now() - perf);\n }\n\n public cleanup(helperToo = true) {\n this.input.cleanup(helperToo);\n this.topbar.cleanup();\n this.selection.cleanup();\n }\n\n public get isForumTopic() {\n return !!(this.isForum && this.threadId);\n }\n\n public async onChangePeer(options: ChatSetPeerOptions, m: ReturnType<typeof middlewarePromise>) {\n const {peerId, threadId} = this;\n\n const searchTab = appSidebarRight.getTab(AppPrivateSearchTab);\n searchTab?.close();\n\n const [\n noForwards,\n isRestricted,\n isAnyGroup,\n _,\n isMegagroup,\n isBroadcast,\n isChannel,\n isBot,\n isForum,\n isAnonymousSending\n ] = await m(Promise.all([\n this.managers.appPeersManager.noForwards(peerId),\n this.managers.appPeersManager.isPeerRestricted(peerId),\n this._isAnyGroup(peerId),\n this.setAutoDownloadMedia(),\n this.managers.appPeersManager.isMegagroup(peerId),\n this.managers.appPeersManager.isBroadcast(peerId),\n this.managers.appPeersManager.isChannel(peerId),\n this.managers.appPeersManager.isBot(peerId),\n this.managers.appPeersManager.isForum(peerId),\n this.managers.appMessagesManager.isAnonymousSending(peerId)\n ]));\n\n // ! WARNING: TEMPORARY, HAVE TO GET TOPIC\n if(isForum && threadId) {\n await m(this.managers.dialogsStorage.getForumTopicOrReload(peerId, threadId));\n }\n\n this.noForwards = noForwards;\n this.isRestricted = isRestricted;\n this.isAnyGroup = isAnyGroup;\n this.isMegagroup = isMegagroup;\n this.isBroadcast = isBroadcast;\n this.isChannel = isChannel;\n this.isBot = isBot;\n this.isForum = isForum;\n this.isAllMessagesForum = isForum && !threadId;\n this.isAnonymousSending = isAnonymousSending;\n\n if(threadId && !this.isForum) {\n options.type = 'discussion';\n }\n\n const type = options.type ?? 'chat';\n this.setType(type);\n\n this.messagesStorageKey = `${this.peerId}_${this.type === 'scheduled' ? 'scheduled' : 'history'}`;\n\n this.container.classList.toggle('no-forwards', this.noForwards);\n\n this.sharedMediaTab = appSidebarRight.createSharedMediaTab();\n this.sharedMediaTabs.push(this.sharedMediaTab);\n\n this.sharedMediaTab.setPeer(peerId, threadId);\n this.input.clearHelper(); // костыль\n this.selection.cleanup(); // TODO: REFACTOR !!!!!!\n }\n\n public setPeer(options: ChatSetPeerOptions) {\n const {peerId, threadId} = options;\n if(!peerId) {\n this.inited = undefined;\n } else if(!this.inited) {\n if(this.init) {\n this.init(/* peerId */);\n this.init = null;\n }\n\n this.inited = true;\n }\n\n // const appMediaViewer = (window as any).appMediaViewer as AppMediaViewerBase<any, any, any>;\n // if(appMediaViewer) {\n // appMediaViewer.close();\n // }\n\n const samePeer = this.appImManager.isSamePeer(this, options);\n if(!samePeer) {\n this.appImManager.dispatchEvent('peer_changing', this);\n this.peerId = peerId || NULL_PEER_ID;\n this.threadId = threadId;\n } else if(this.setPeerPromise) {\n return;\n }\n\n if(!peerId) {\n appSidebarRight.toggleSidebar(false);\n this.cleanup(true);\n this.bubbles.setPeer({samePeer: false, peerId});\n this.peerId = 0;\n this.appImManager.dispatchEvent('peer_changed', this);\n\n appSidebarRight.replaceSharedMediaTab();\n this.destroySharedMediaTab();\n this.sharedMediaTab = undefined;\n\n return;\n }\n\n this.peerChanged = samePeer;\n\n const bubblesSetPeerPromise = this.bubbles.setPeer({...options, samePeer});\n const setPeerPromise = this.setPeerPromise = bubblesSetPeerPromise.then((result) => {\n return result.promise;\n }).catch(noop).finally(() => {\n if(this.setPeerPromise === setPeerPromise) {\n this.setPeerPromise = null;\n }\n });\n\n return bubblesSetPeerPromise;\n }\n\n public destroySharedMediaTab(tab = this.sharedMediaTab) {\n if(!tab) {\n return;\n }\n\n indexOfAndSplice(this.sharedMediaTabs, tab);\n tab.destroy();\n }\n\n public async setAutoDownloadMedia() {\n this.autoDownload = await getAutoDownloadSettingsByPeerId(this.peerId);\n }\n\n public setMessageId(messageId?: number, mediaTimestamp?: number) {\n return this.setPeer({\n peerId: this.peerId,\n threadId: this.threadId,\n lastMsgId: messageId,\n mediaTimestamp\n });\n }\n\n public async finishPeerChange(options: {\n isTarget?: boolean,\n isJump?: boolean,\n lastMsgId?: number,\n startParam?: string,\n middleware: () => boolean\n }) {\n if(this.peerChanged) return;\n\n const peerId = this.peerId;\n this.peerChanged = true;\n this.wasAlreadyUsed = true;\n\n const {middleware} = options;\n\n this.cleanup(false);\n\n const sharedMediaTab = this.sharedMediaTab;\n\n const callbacksPromise = Promise.all([\n this.topbar.finishPeerChange(options),\n this.bubbles.finishPeerChange(),\n this.input.finishPeerChange(options),\n sharedMediaTab.fillProfileElements()\n ]);\n\n const callbacks = await callbacksPromise;\n sharedMediaTab.loadSidebarMedia(true);\n\n if(!middleware()) {\n return;\n }\n\n callbacks.forEach((callback) => {\n callback?.();\n });\n\n appSidebarRight.replaceSharedMediaTab(sharedMediaTab);\n\n this.sharedMediaTabs.filter((tab) => tab !== sharedMediaTab).forEach((tab) => this.destroySharedMediaTab(tab));\n\n this.container.dataset.type = this.type;\n this.log.setPrefix('CHAT-' + peerId + '-' + this.type);\n\n this.appImManager.dispatchEvent('peer_changed', this);\n }\n\n public getMessage(mid: number) {\n return this.managers.appMessagesManager.getMessageFromStorage(this.messagesStorageKey, mid);\n }\n\n public async getMidsByMid(mid: number) {\n return this.managers.appMessagesManager.getMidsByMessage(await this.getMessage(mid));\n }\n\n public getHistoryStorage(ignoreThreadId?: boolean) {\n return this.managers.appMessagesManager.getHistoryStorageTransferable(this.peerId, ignoreThreadId ? undefined : this.threadId)\n .then((historyStorageTransferable) => {\n return {\n ...historyStorageTransferable,\n history: SlicedArray.fromJSON<number>(historyStorageTransferable.historySerialized)\n }\n });\n }\n\n public getDialogOrTopic() {\n return this.isForum && this.threadId ? this.managers.dialogsStorage.getForumTopic(this.peerId, this.threadId) : this.managers.dialogsStorage.getDialogOnly(this.peerId);\n }\n\n public getHistoryMaxId() {\n return this.getHistoryStorage().then((historyStorage) => historyStorage.maxId);\n }\n\n public async _isAnyGroup(peerId: PeerId) {\n return peerId === rootScope.myId || peerId === REPLIES_PEER_ID || (await this.managers.appPeersManager.isAnyGroup(peerId));\n }\n\n public initSearch(query?: string) {\n if(!this.peerId) return;\n\n if(mediaSizes.isMobile) {\n if(!this.search) {\n this.search = new ChatSearch(this.topbar, this, query);\n } else {\n this.search.setQuery(query);\n }\n } else {\n let tab = appSidebarRight.getTab(AppPrivateSearchTab);\n if(!tab) {\n tab = appSidebarRight.createTab(AppPrivateSearchTab);\n }\n\n tab.open(this.peerId, this.threadId, this.bubbles.onDatePick, query);\n }\n }\n\n public canSend(action?: ChatRights) {\n return this.managers.appMessagesManager.canSendToPeer(this.peerId, this.threadId, action);\n }\n\n public isStartButtonNeeded() {\n return Promise.all([\n this.managers.appPeersManager.isBot(this.peerId),\n this.managers.appMessagesManager.getDialogOnly(this.peerId),\n this.getHistoryStorage(true)\n ]).then(([isBot, dialog, historyStorage]) => {\n return isBot && !dialog && !historyStorage.history.length;\n });\n }\n\n public getMessageSendingParams(): MessageSendingParams {\n return {\n threadId: this.threadId,\n replyToMsgId: this.input.replyToMsgId,\n scheduleDate: this.input.scheduleDate,\n silent: this.input.sendSilent,\n sendAsPeerId: this.input.sendAsPeerId,\n updateStickersetOrder: rootScope.settings.stickers.dynamicPackOrder\n };\n }\n\n public isOurMessage(message: Message.message | Message.messageService) {\n return message.fromId === rootScope.myId || (!!message.pFlags.out && this.isMegagroup);\n }\n\n public isOutMessage(message: Message.message | Message.messageService) {\n const fwdFrom = (message as Message.message).fwd_from;\n const isOut = this.isOurMessage(message) && (!fwdFrom || this.peerId !== rootScope.myId);\n return !!isOut;\n }\n\n public isAvatarNeeded(message: Message.message | Message.messageService) {\n return this.isAnyGroup && !this.isOutMessage(message);\n }\n\n public isPinnedMessagesNeeded() {\n return this.type === 'chat' || this.isForum;\n }\n\n public canGiftPremium() {\n const peerId = this.peerId;\n return peerId.isUser() && this.managers.appProfileManager.canGiftPremium(this.peerId.toUserId());\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {State} from '../config/state';\nimport rootScope from '../lib/rootScope';\n\nexport type ChatAutoDownloadSettings = {\n photo: number,\n video: number,\n file: number\n};\n\nexport default async function getAutoDownloadSettingsByPeerId(peerId: PeerId): Promise<ChatAutoDownloadSettings> {\n let type: keyof State['settings']['autoDownload'];\n\n let photoSizeMax = 0, videoSizeMax = 0, fileSizeMax = 0;\n const settings = rootScope.settings;\n const appPeersManager = rootScope.managers.appPeersManager;\n if(!settings.autoDownloadNew.pFlags.disabled && peerId) {\n if(peerId.isUser()) {\n if(await appPeersManager.isContact(peerId)) {\n type = 'contacts';\n } else {\n type = 'private';\n }\n } else if(await appPeersManager.isBroadcast(peerId)) {\n type = 'channels';\n } else {\n type = 'groups';\n }\n\n if(settings.autoDownload.photo[type]) photoSizeMax = settings.autoDownloadNew.photo_size_max;\n if(settings.autoDownload.video[type]) videoSizeMax = settings.autoDownloadNew.video_size_max;\n if(settings.autoDownload.file[type]) fileSizeMax = settings.autoDownloadNew.file_size_max;\n }\n\n return {\n photo: photoSizeMax,\n video: videoSizeMax,\n file: fileSizeMax\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {AppImManager} from '../../lib/appManagers/appImManager';\nimport ButtonIcon from '../buttonIcon';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport {IS_APPLE, IS_MOBILE} from '../../environment/userAgent';\nimport appNavigationController from '../appNavigationController';\nimport {_i18n} from '../../lib/langPack';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport isSelectionEmpty from '../../helpers/dom/isSelectionEmpty';\nimport {MarkdownType} from '../../helpers/dom/getRichElementValue';\nimport getVisibleRect from '../../helpers/dom/getVisibleRect';\nimport clamp from '../../helpers/number/clamp';\nimport matchUrl from '../../lib/richTextProcessor/matchUrl';\nimport matchUrlProtocol from '../../lib/richTextProcessor/matchUrlProtocol';\nimport hasMarkupInSelection from '../../helpers/dom/hasMarkupInSelection';\n\nexport default class MarkupTooltip {\n public container: HTMLElement;\n private wrapper: HTMLElement;\n private buttons: {[type in MarkdownType]: HTMLElement} = {} as any;\n private linkBackButton: HTMLElement;\n private linkApplyButton: HTMLButtonElement;\n private hideTimeout: number;\n private addedListener = false;\n private waitingForMouseUp = false;\n private linkInput: HTMLInputElement;\n private savedRange: Range;\n private mouseUpCounter: number = 0;\n // private log: ReturnType<typeof logger>;\n\n constructor(private appImManager: AppImManager) {\n // this.log = logger('MARKUP');\n }\n\n private init() {\n this.container = document.createElement('div');\n this.container.classList.add('markup-tooltip', 'z-depth-1', 'hide');\n\n this.wrapper = document.createElement('div');\n this.wrapper.classList.add('markup-tooltip-wrapper');\n\n const tools1 = document.createElement('div');\n const tools2 = document.createElement('div');\n tools1.classList.add('markup-tooltip-tools');\n tools2.classList.add('markup-tooltip-tools');\n\n const arr = ['bold', 'italic', 'underline', 'strikethrough', 'monospace', 'spoiler', 'link'] as (keyof MarkupTooltip['buttons'])[];\n arr.forEach((c) => {\n const button = ButtonIcon(c, {noRipple: true});\n tools1.append(this.buttons[c] = button);\n\n if(c !== 'link') {\n button.addEventListener('mousedown', (e) => {\n cancelEvent(e);\n this.appImManager.chat.input.applyMarkdown(c);\n this.cancelClosening();\n\n /* this.mouseUpCounter = 0;\n this.setMouseUpEvent(); */\n // this.hide();\n });\n } else {\n attachClickEvent(button, (e) => {\n cancelEvent(e);\n this.showLinkEditor();\n this.cancelClosening();\n });\n }\n });\n\n this.linkBackButton = ButtonIcon('left', {noRipple: true});\n this.linkInput = document.createElement('input');\n _i18n(this.linkInput, 'MarkupTooltip.LinkPlaceholder', undefined, 'placeholder');\n this.linkInput.classList.add('input-clear');\n this.linkInput.addEventListener('keydown', (e) => {\n const valid = !this.linkInput.value.length || !!matchUrl(this.linkInput.value);// /^(http)|(https):\\/\\//i.test(this.linkInput.value);\n\n if(e.key === 'Enter') {\n if(!valid) {\n if(this.linkInput.classList.contains('error')) {\n this.linkInput.classList.remove('error');\n void this.linkInput.offsetLeft; // reflow\n }\n\n this.linkInput.classList.add('error');\n } else {\n this.applyLink(e);\n }\n }\n });\n\n this.linkInput.addEventListener('input', (e) => {\n const valid = this.isLinkValid();\n\n this.linkInput.classList.toggle('is-valid', valid);\n this.linkInput.classList.remove('error');\n });\n\n this.linkBackButton.addEventListener('mousedown', (e) => {\n // this.log('linkBackButton click');\n cancelEvent(e);\n this.container.classList.remove('is-link');\n // input.value = '';\n this.resetSelection();\n this.setTooltipPosition();\n this.cancelClosening();\n });\n\n this.linkApplyButton = ButtonIcon('check markup-tooltip-link-apply', {noRipple: true});\n this.linkApplyButton.addEventListener('mousedown', (e) => {\n // this.log('linkApplyButton click');\n this.applyLink(e);\n });\n\n const applyDiv = document.createElement('div');\n applyDiv.classList.add('markup-tooltip-link-apply-container');\n\n const delimiter1 = document.createElement('span');\n const delimiter2 = document.createElement('span');\n const delimiter3 = document.createElement('span');\n delimiter1.classList.add('markup-tooltip-delimiter');\n delimiter2.classList.add('markup-tooltip-delimiter');\n delimiter3.classList.add('markup-tooltip-delimiter');\n tools1.insertBefore(delimiter1, this.buttons.link);\n applyDiv.append(delimiter3, this.linkApplyButton);\n tools2.append(this.linkBackButton, delimiter2, this.linkInput, applyDiv);\n // tools1.insertBefore(delimiter2, this.buttons.link.nextSibling);\n\n this.wrapper.append(tools1, tools2);\n this.container.append(this.wrapper);\n document.body.append(this.container);\n\n window.addEventListener('resize', () => {\n this.hide();\n });\n }\n\n public showLinkEditor() {\n if(!this.container || !this.container.classList.contains('is-visible')) { // * if not inited yet (Ctrl+A + Ctrl+K)\n this.show();\n }\n\n const button = this.buttons.link;\n this.container.classList.add('is-link');\n\n const selection = document.getSelection();\n this.savedRange = selection.getRangeAt(0);\n\n if(button.classList.contains('active')) {\n const startContainer = this.savedRange.startContainer;\n const anchor = startContainer.parentElement as HTMLAnchorElement;\n this.linkInput.value = anchor.href;\n } else {\n this.linkInput.value = '';\n }\n\n this.setTooltipPosition(true);\n\n setTimeout(() => {\n this.linkInput.focus(); // !!! instant focus will break animation\n }, 200);\n this.linkInput.classList.toggle('is-valid', this.isLinkValid());\n }\n\n private applyLink(e: Event) {\n cancelEvent(e);\n this.resetSelection();\n let url = this.linkInput.value;\n if(url && !matchUrlProtocol(url)) {\n url = 'https://' + url;\n }\n this.appImManager.chat.input.applyMarkdown('link', url);\n setTimeout(() => {\n this.hide();\n }, 0);\n }\n\n private isLinkValid() {\n return !this.linkInput.value.length || !!matchUrl(this.linkInput.value);\n }\n\n private resetSelection(range: Range = this.savedRange) {\n const selection = window.getSelection();\n selection.removeAllRanges();\n selection.addRange(range);\n this.appImManager.chat.input.messageInput.focus();\n }\n\n public hide() {\n // return;\n\n if(this.init) return;\n\n this.container.classList.remove('is-visible');\n // document.removeEventListener('mouseup', this.onMouseUp);\n document.removeEventListener('mouseup', this.onMouseUpSingle);\n this.waitingForMouseUp = false;\n\n appNavigationController.removeByType('markup');\n\n if(this.hideTimeout) clearTimeout(this.hideTimeout);\n this.hideTimeout = window.setTimeout(() => {\n this.hideTimeout = undefined;\n this.container.classList.add('hide');\n this.container.classList.remove('is-link');\n }, 200);\n }\n\n public getActiveMarkupButton() {\n const currentMarkups: Set<HTMLElement> = new Set();\n\n // const nodes = getSelectedNodes();\n // const parents = [...new Set(nodes.map((node) => node.parentNode))];\n // // if(parents.length > 1 && parents) return [];\n\n // (parents as HTMLElement[]).forEach((node) => {\n // for(const type in markdownTags) {\n // const tag = markdownTags[type as MarkdownType];\n // const closest = node.closest(tag.match + ', [contenteditable=\"true\"]');\n // if(closest !== this.appImManager.chat.input.messageInput) {\n // currentMarkups.add(this.buttons[type as MarkdownType]);\n // }\n // }\n // });\n\n const types = Object.keys(this.buttons) as MarkdownType[];\n const markup = hasMarkupInSelection(types);\n types.forEach((type) => {\n if(markup[type]) {\n currentMarkups.add(this.buttons[type as MarkdownType]);\n }\n });\n\n return [...currentMarkups];\n }\n\n public setActiveMarkupButton() {\n const activeButtons = this.getActiveMarkupButton();\n\n for(const i in this.buttons) {\n // @ts-ignore\n const button = this.buttons[i];\n button.classList.toggle('active', activeButtons.includes(button));\n }\n }\n\n private setTooltipPosition(isLinkToggle = false) {\n const selection = document.getSelection();\n const range = selection.getRangeAt(0);\n\n const bodyRect = document.body.getBoundingClientRect();\n const selectionRect = range.getBoundingClientRect();\n const inputRect = this.appImManager.chat.input.rowsWrapper.getBoundingClientRect();\n\n this.container.style.maxWidth = inputRect.width + 'px';\n\n const visibleRect = getVisibleRect(undefined, this.appImManager.chat.input.messageInput, false, selectionRect);\n\n const selectionTop = visibleRect.rect.top/* selectionRect.top */ + (bodyRect.top * -1);\n\n const currentTools = this.container.classList.contains('is-link') ? this.wrapper.lastElementChild : this.wrapper.firstElementChild;\n\n const sizesRect = currentTools.getBoundingClientRect();\n const top = selectionTop - sizesRect.height - 8;\n\n const minX = inputRect.left;\n const maxX = (inputRect.left + inputRect.width) - Math.min(inputRect.width, sizesRect.width);\n let left: number;\n if(isLinkToggle) {\n const containerRect = this.container.getBoundingClientRect();\n left = clamp(containerRect.left, minX, maxX);\n } else {\n const x = selectionRect.left + (selectionRect.width - sizesRect.width) / 2;\n left = clamp(x, minX, maxX);\n }\n\n /* const isClamped = x !== minX && x !== maxX && (left === minX || left === maxX || this.container.getBoundingClientRect().left >= maxX);\n\n if(isLinkToggle && this.container.classList.contains('is-link') && !isClamped) return; */\n\n this.container.style.transform = `translate3d(${left}px, ${top}px, 0)`;\n }\n\n public show() {\n if(this.init) {\n this.init();\n this.init = null;\n }\n\n if(isSelectionEmpty()) {\n this.hide();\n return;\n }\n\n if(this.hideTimeout !== undefined) {\n clearTimeout(this.hideTimeout);\n }\n\n if(this.container.classList.contains('is-visible')) {\n return;\n }\n\n this.setActiveMarkupButton();\n\n this.container.classList.remove('is-link');\n const isFirstShow = this.container.classList.contains('hide');\n if(isFirstShow) {\n this.container.classList.remove('hide');\n this.container.classList.add('no-transition');\n }\n\n this.setTooltipPosition();\n\n if(isFirstShow) {\n void this.container.offsetLeft; // reflow\n this.container.classList.remove('no-transition');\n }\n\n this.container.classList.add('is-visible');\n\n if(!IS_MOBILE) {\n appNavigationController.pushItem({\n type: 'markup',\n onPop: () => {\n this.hide();\n }\n });\n }\n\n // this.log('selection', selectionRect, activeButton);\n }\n\n /* private onMouseUp = (e: Event) => {\n this.log('onMouseUp');\n if(findUpClassName(e.target, 'markup-tooltip')) return;\n\n this.hide();\n //document.removeEventListener('mouseup', this.onMouseUp);\n }; */\n\n private onMouseUpSingle = (e?: Event) => {\n // this.log('onMouseUpSingle');\n this.waitingForMouseUp = false;\n\n if(IS_TOUCH_SUPPORTED) {\n e && cancelEvent(e);\n if(this.mouseUpCounter++ === 0) {\n this.resetSelection(this.savedRange);\n } else {\n this.hide();\n return;\n }\n }\n\n this.show();\n\n /* !isTouchSupported && document.addEventListener('mouseup', this.onMouseUp); */\n };\n\n public setMouseUpEvent() {\n if(this.waitingForMouseUp) return;\n this.waitingForMouseUp = true;\n\n // this.log('setMouseUpEvent');\n\n document.addEventListener('mouseup', this.onMouseUpSingle, {once: true});\n }\n\n public cancelClosening() {\n if(IS_TOUCH_SUPPORTED && !IS_APPLE) {\n document.removeEventListener('mouseup', this.onMouseUpSingle);\n document.addEventListener('mouseup', (e) => {\n cancelEvent(e);\n this.mouseUpCounter = 1;\n this.waitingForMouseUp = false;\n this.setMouseUpEvent();\n }, {once: true});\n }\n }\n\n public handleSelection() {\n if(this.addedListener) return;\n this.addedListener = true;\n document.addEventListener('selectionchange', (e) => {\n // this.log('selectionchange');\n\n if(document.activeElement === this.linkInput) {\n return;\n }\n\n const messageInput = this.appImManager.chat.input.messageInput;\n if(document.activeElement !== messageInput) {\n this.hide();\n return;\n }\n\n const selection = document.getSelection();\n if(isSelectionEmpty(selection)) {\n this.hide();\n return;\n }\n\n if(IS_TOUCH_SUPPORTED) {\n if(IS_APPLE) {\n this.show();\n this.setTooltipPosition(); // * because can skip this in .show();\n } else {\n if(this.mouseUpCounter === 2) {\n this.mouseUpCounter = 0;\n return;\n }\n\n this.savedRange = selection.getRangeAt(0);\n this.setMouseUpEvent();\n /* document.addEventListener('touchend', (e) => {\n cancelEvent(e);\n this.resetSelection(range);\n this.show();\n }, {once: true, passive: false}); */\n }\n } else if(this.container && this.container.classList.contains('is-visible')) {\n this.setActiveMarkupButton();\n this.setTooltipPosition();\n } else if(messageInput.matches(':active')) {\n this.setMouseUpEvent();\n } else {\n this.show();\n }\n });\n\n document.addEventListener('beforeinput', (e) => {\n if(e.inputType === 'historyRedo' || e.inputType === 'historyUndo') {\n e.target.addEventListener('input', () => this.setActiveMarkupButton(), {once: true});\n }\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport generatePathData from '../../helpers/generatePathData';\nimport {FormatterArguments, i18n, LangPackKey} from '../../lib/langPack';\n\nexport default class ChatDragAndDrop {\n container: HTMLDivElement;\n svg: SVGSVGElement;\n outlineWrapper: HTMLDivElement;\n path: SVGPathElement;\n\n constructor(appendTo: HTMLElement, private options: {\n icon?: string,\n header: LangPackKey,\n headerArgs?: FormatterArguments,\n subtitle?: LangPackKey,\n onDrop: (e: DragEvent) => void\n }) {\n this.container = document.createElement('div');\n this.container.classList.add('drop', 'z-depth-1');\n\n this.outlineWrapper = document.createElement('div');\n this.outlineWrapper.classList.add('drop-outline-wrapper');\n\n this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n this.svg.classList.add('drop-outline');\n\n this.path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n this.path.classList.add('drop-outline-path');\n\n let dropIcon: HTMLElement;\n if(options.icon) {\n dropIcon = document.createElement('div');\n dropIcon.classList.add('drop-icon', 'tgico-' + options.icon);\n }\n\n const dropHeader = document.createElement('div');\n dropHeader.classList.add('drop-header');\n dropHeader.append(i18n(options.header, options.headerArgs));\n\n let dropSubtitle: HTMLElement;\n if(options.subtitle) {\n dropSubtitle = document.createElement('div');\n dropSubtitle.classList.add('drop-subtitle');\n dropSubtitle.append(i18n(options.subtitle));\n }\n\n this.svg.append(this.path);\n this.outlineWrapper.append(this.svg);\n\n this.container.append(...[this.outlineWrapper, dropIcon, dropHeader, dropSubtitle].filter(Boolean));\n appendTo.append(this.container);\n\n this.container.addEventListener('dragover', this.onDragOver);\n this.container.addEventListener('dragleave', this.onDragLeave);\n this.container.addEventListener('drop', this.onDrop);\n }\n\n onDragOver = (e: DragEvent) => {\n this.container.classList.add('is-dragover');\n // SetTransition(this.container, 'is-dragover', true, 500);\n };\n\n onDragLeave = (e: DragEvent) => {\n this.container.classList.remove('is-dragover');\n // SetTransition(this.container, 'is-dragover', false, 500);\n };\n\n onDrop = (e: DragEvent) => {\n this.options.onDrop(e);\n };\n\n destroy() {\n delete this.options;\n this.container.remove();\n this.container.removeEventListener('dragover', this.onDragOver);\n this.container.removeEventListener('dragleave', this.onDragLeave);\n this.container.removeEventListener('drop', this.onDrop);\n }\n\n setPath() {\n const rect = this.outlineWrapper.getBoundingClientRect();\n this.svg.setAttributeNS(null, 'preserveAspectRatio', 'none');\n this.svg.setAttributeNS(null, 'viewBox', `0 0 ${rect.width} ${rect.height}`);\n this.svg.setAttributeNS(null, 'width', `${rect.width}`);\n this.svg.setAttributeNS(null, 'height', `${rect.height}`);\n\n const radius = 10;\n // const strokeWidth = 2;\n const sizeX = rect.width - radius;\n const sizeY = rect.height - radius;\n const pos = radius / 2;\n const d = generatePathData(pos, pos, sizeX, sizeY, radius, radius, radius, radius);\n this.path.setAttributeNS(null, 'd', d);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {doubleRaf} from '../schedulers';\n\nexport default function disableTransition(elements: HTMLElement[]) {\n elements.forEach((el) => el.classList.add('no-transition'));\n\n doubleRaf().then(() => {\n elements.forEach((el) => el.classList.remove('no-transition'));\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\nexport const MAX_SPEED = 8.2;\nexport const MIN_SPEED = 0.8;\n\n// import { MIN_SPEED, MAX_SPEED } from './BlobDrawable';\n\ntype Radius = number[];\n\nexport default class LineBlobDrawable {\n public maxRadius: number;\n public minRadius: number;\n private N: number;\n private radius: Radius;\n private radiusNext: Radius;\n private progress: number[];\n private speed: number[];\n\n constructor(n: number) {\n this.maxRadius = 10;\n this.minRadius = 0;\n\n this.N = n;\n this.radius = new Array(n + 1);\n\n this.radiusNext = new Array(n + 1);\n this.progress = new Array(n + 1);\n this.speed = new Array(n + 1);\n\n for(let i = 0; i <= n; i++) {\n this.generateBlob(this.radius, i);\n this.generateBlob(this.radiusNext, i);\n this.progress[i] = 0;\n }\n }\n\n private generateBlob(radius: Radius, i: number) {\n const {maxRadius, minRadius, speed} = this;\n\n const radDif = maxRadius - minRadius;\n radius[i] = minRadius + Math.random() * radDif;\n speed[i] = 0.017 + 0.003 * Math.random();\n }\n\n private generateNextBlob() {\n const {radius, radiusNext, progress, N} = this;\n for(let i = 0; i < N; i++) {\n this.generateBlob(radius, i);\n this.generateBlob(radiusNext, i);\n progress[i] = 0.0;\n }\n }\n\n public update(amplitude: number, speedScale: number) {\n const {N, progress, speed, radius, radiusNext} = this;\n for(let i = 0; i <= N; i++) {\n progress[i] += (speed[i] * MIN_SPEED) + amplitude * speed[i] * MAX_SPEED * speedScale;\n if(progress[i] >= 1.0) {\n progress[i] = 0.0;\n radius[i] = radiusNext[i];\n this.generateBlob(radiusNext, i);\n }\n }\n }\n\n public draw(left: number, top: number, right: number, bottom: number, canvas: HTMLCanvasElement, paint: (ctx: CanvasRenderingContext2D) => void, pinnedTop: number, progressToPinned: number) {\n if(canvas.getContext) {\n const ctx = canvas.getContext('2d');\n // ctx.globalAlpha = 0.5;\n // ctx.lineWidth = 1;\n\n ctx.beginPath();\n ctx.moveTo(right, bottom);\n ctx.lineTo(left, bottom);\n\n const {radius, radiusNext, N} = this;\n for(let i = 0; i <= N; i++) {\n if(i === 0) {\n const progress = this.progress[i];\n const r1 = radius[i] * (1.0 - progress) + radiusNext[i] * progress;\n const y = (top - r1) * progressToPinned + pinnedTop * (1.0 - progressToPinned);\n ctx.lineTo(left, y);\n } else {\n const progress = this.progress[i - 1];\n const r1 = radius[i - 1] * (1.0 - progress) + radiusNext[i - 1] * progress;\n const progressNext = this.progress[i];\n const r2 = radius[i] * (1.0 - progressNext) + radiusNext[i] * progressNext;\n const x1 = (right - left) / N * (i - 1);\n const x2 = (right - left) / N * i;\n const cx = x1 + (x2 - x1) / 2;\n\n const y1 = (top - r1) * progressToPinned + pinnedTop * (1.0 - progressToPinned);\n const y2 = (top - r2) * progressToPinned + pinnedTop * (1.0 - progressToPinned);\n ctx.bezierCurveTo(cx, y1, cx, y2, x2, y2);\n if(i === N) {\n ctx.lineTo(right, bottom);\n }\n }\n }\n\n // ctx.scale(1.0, 1.0);\n paint(ctx);\n ctx.fill();\n ctx.closePath();\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\nimport GROUP_CALL_STATE from '../lib/calls/groupCallState';\nimport LineBlobDrawable from './lineBlobDrawable';\n\nexport class WeavingState {\n public shader: (ctx: CanvasRenderingContext2D, left: number, top: number, right: number, bottom: number) => void;\n\n constructor(public stateId: GROUP_CALL_STATE) {\n this.createGradient(stateId);\n }\n\n public createGradient(stateId: GROUP_CALL_STATE) {\n this.shader = (ctx, left, top, right, bottom) => {\n ctx.fillStyle = WeavingState.getGradientFromType(ctx, stateId, left, top, right, bottom);\n };\n }\n\n // Android colors\n static getGradientFromType(ctx: CanvasRenderingContext2D, type: GROUP_CALL_STATE, x0: number, y0: number, x1: number, y1: number) {\n const gradient = ctx.createLinearGradient(x0, y0, x1, y1);\n if(type === GROUP_CALL_STATE.MUTED_BY_ADMIN) {\n gradient.addColorStop(0, '#F05459');\n gradient.addColorStop(.4, '#766EE9');\n gradient.addColorStop(1, '#57A4FE');\n } else if(type === GROUP_CALL_STATE.UNMUTED) {\n gradient.addColorStop(0, '#52CE5D');\n gradient.addColorStop(1, '#00B1C0');\n } else if(type === GROUP_CALL_STATE.MUTED) {\n gradient.addColorStop(0, '#0976E3');\n gradient.addColorStop(1, '#2BCEFF');\n } else if(type === GROUP_CALL_STATE.CONNECTING) {\n gradient.addColorStop(0, '#8599aa');\n gradient.addColorStop(1, '#8599aa');\n }\n\n return gradient;\n }\n\n update(height: number, width: number, dt: number, amplitude: number) {\n // TODO: move gradient here\n }\n}\n\nexport default class TopbarWeave {\n private focused: boolean;\n private resizing: boolean;\n private lastUpdateTime: number;\n private amplitude: number;\n private amplitude2: number;\n\n private states: Map<GROUP_CALL_STATE, WeavingState>;\n private previousState: WeavingState;\n private currentState: WeavingState;\n private progressToState: number;\n\n private scale: number;\n private left: number;\n private top: number;\n private right: number;\n private bottom: number;\n\n private mounted: boolean;\n private media: MediaQueryList;\n\n private container: HTMLDivElement;\n private canvas: HTMLCanvasElement;\n\n private resizeHandler: number;\n private raf: number;\n\n private lbd: LineBlobDrawable;\n private lbd1: LineBlobDrawable;\n private lbd2: LineBlobDrawable;\n\n private animateToAmplitude: number;\n private animateAmplitudeDiff: number;\n private animateAmplitudeDiff2: number;\n\n constructor() {\n this.focused = true;\n this.resizing = false;\n this.lastUpdateTime = Date.now();\n this.amplitude = 0.0;\n this.amplitude2 = 0.0;\n\n this.states = new Map([\n [GROUP_CALL_STATE.UNMUTED, new WeavingState(GROUP_CALL_STATE.UNMUTED)],\n [GROUP_CALL_STATE.MUTED, new WeavingState(GROUP_CALL_STATE.MUTED)],\n [GROUP_CALL_STATE.MUTED_BY_ADMIN, new WeavingState(GROUP_CALL_STATE.MUTED_BY_ADMIN)],\n [GROUP_CALL_STATE.CONNECTING, new WeavingState(GROUP_CALL_STATE.CONNECTING)]\n ]);\n this.previousState = null;\n this.currentState = this.states.get(GROUP_CALL_STATE.CONNECTING);\n this.progressToState = 1.0;\n }\n\n public componentDidMount() {\n if(this.mounted) {\n return;\n }\n\n this.mounted = true;\n // window.addEventListener('blur', this.handleBlur);\n // window.addEventListener('focus', this.handleFocus);\n window.addEventListener('resize', this.handleResize);\n this.media = window.matchMedia('screen and (min-resolution: 2dppx)');\n this.media.addEventListener('change', this.handleDevicePixelRatioChanged);\n\n this.setSize();\n this.forceUpdate();\n\n this.lbd = new LineBlobDrawable(3);\n this.lbd1 = new LineBlobDrawable(7);\n this.lbd2 = new LineBlobDrawable(8);\n this.setAmplitude(this.amplitude);\n\n this.draw();\n }\n\n public componentWillUnmount() {\n this.mounted = false;\n // window.removeEventListener('blur', this.handleBlur);\n // window.removeEventListener('focus', this.handleFocus);\n window.removeEventListener('resize', this.handleResize);\n this.media.addEventListener('change', this.handleDevicePixelRatioChanged);\n\n const {canvas} = this;\n const ctx = canvas.getContext('2d');\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n\n private setSize() {\n this.scale = window.devicePixelRatio;\n this.top = 20 * this.scale;\n this.right = (this.mounted ? this.container.offsetWidth : 1261) * this.scale;\n this.bottom = (this.mounted ? this.container.offsetHeight : 68) * this.scale;\n this.left = 0 * this.scale;\n this.setCanvasSize();\n }\n\n private setCanvasSize() {\n this.canvas.width = this.right;\n this.canvas.height = this.bottom;\n }\n\n private handleDevicePixelRatioChanged = (e: Event) => {\n this.setSize();\n this.forceUpdate();\n }\n\n private handleResize = () => {\n if(this.resizeHandler) {\n clearTimeout(this.resizeHandler);\n this.resizeHandler = null;\n }\n\n this.resizing = true;\n this.resizeCanvas();\n this.resizeHandler = window.setTimeout(() => {\n this.resizing = false;\n this.invokeDraw();\n }, 250);\n }\n\n private resizeCanvas() {\n this.scale = window.devicePixelRatio;\n this.right = this.container.offsetWidth * this.scale;\n\n this.forceUpdate();\n this.invokeDraw();\n }\n\n public handleFocus = () => {\n this.focused = true;\n this.invokeDraw();\n }\n\n public handleBlur = () => {\n this.focused = false;\n }\n\n private invokeDraw = () => {\n if(this.raf) return;\n\n this.draw();\n }\n\n private draw = (force = false) => {\n this.raf = null;\n if(!this.mounted) {\n return;\n }\n const {lbd, lbd1, lbd2, scale, left, top, right, bottom, currentState, previousState, focused, resizing, canvas} = this;\n if(!focused && !resizing && this.progressToState >= 1.0) {\n return;\n }\n\n // console.log('[top] draw', [focused, resizing, this.mounted]);\n\n const newTime = Date.now();\n let dt = (newTime - this.lastUpdateTime);\n if(dt > 20) {\n dt = 17;\n }\n\n // console.log('draw start', this.amplitude, this.animateToAmplitude);\n if(this.animateToAmplitude !== this.amplitude) {\n this.amplitude += this.animateAmplitudeDiff * dt;\n if(this.animateAmplitudeDiff > 0) {\n if(this.amplitude > this.animateToAmplitude) {\n this.amplitude = this.animateToAmplitude;\n }\n } else {\n if(this.amplitude < this.animateToAmplitude) {\n this.amplitude = this.animateToAmplitude;\n }\n }\n }\n\n if(this.animateToAmplitude !== this.amplitude2) {\n this.amplitude2 += this.animateAmplitudeDiff2 * dt;\n if(this.animateAmplitudeDiff2 > 0) {\n if(this.amplitude2 > this.animateToAmplitude) {\n this.amplitude2 = this.animateToAmplitude;\n }\n } else {\n if(this.amplitude2 < this.animateToAmplitude) {\n this.amplitude2 = this.animateToAmplitude;\n }\n }\n }\n\n if(previousState) {\n this.progressToState += dt / 250;\n if(this.progressToState > 1) {\n this.progressToState = 1;\n this.previousState = null;\n }\n }\n\n const {amplitude, amplitude2, progressToState} = this;\n\n const top1 = 6 * amplitude2 * scale;\n const top2 = 6 * amplitude2 * scale;\n\n const ctx = canvas.getContext('2d');\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n lbd.minRadius = 0;\n lbd.maxRadius = (2 + 2 * amplitude) * scale;\n lbd1.minRadius = 0;\n lbd1.maxRadius = (3 + 9 * amplitude) * scale;\n lbd2.minRadius = 0;\n lbd2.maxRadius = (3 + 9 * amplitude) * scale;\n\n lbd.update(amplitude, 0.3);\n lbd1.update(amplitude, 0.7);\n lbd2.update(amplitude, 0.7);\n\n for(let i = 0; i < 2; i++) {\n if(i === 0 && !previousState) {\n continue;\n }\n\n let alpha = 1;\n let state: WeavingState = null;\n if(i === 0) {\n alpha = 1 - progressToState;\n state = previousState;\n // previousState.setToPaint(paint);\n } else {\n alpha = previousState ? progressToState : 1;\n currentState.update(bottom - top, right - left, dt, amplitude);\n state = currentState;\n // currentState.setToPaint(paint);\n }\n\n const paint1 = (ctx: CanvasRenderingContext2D) => {\n ctx.globalAlpha = 0.3 * alpha;\n state.shader(ctx, left, top, right, bottom);\n };\n const paint = (ctx: CanvasRenderingContext2D) => {\n ctx.globalAlpha = i === 0 ? 1 : alpha;\n state.shader(ctx, left, top, right, bottom);\n };\n\n lbd1.draw(left, top - top1, right, bottom, canvas, paint1, top, 1.0);\n lbd2.draw(left, top - top2, right, bottom, canvas, paint1, top, 1.0);\n lbd.draw(left, top, right, bottom, canvas, paint, top, 1.0);\n }\n\n if(!force) {\n this.raf = requestAnimationFrame(() => this.draw());\n }\n };\n\n public setCurrentState = (stateId: GROUP_CALL_STATE, animated: boolean) => {\n const {currentState, states} = this;\n\n if(currentState?.stateId === stateId) {\n return;\n }\n\n this.previousState = animated ? currentState : null;\n this.currentState = states.get(stateId);\n this.progressToState = this.previousState ? 0.0 : 1.0;\n };\n\n public setAmplitude(value: number) {\n const {amplitude} = this;\n this.animateToAmplitude = value;\n this.animateAmplitudeDiff = (value - amplitude) / 250;\n this.animateAmplitudeDiff2 = (value - amplitude) / 120;\n }\n\n private forceUpdate() {\n this.setCanvasSize();\n }\n\n public render(className: string) {\n const container = this.container = document.createElement('div');\n container.classList.add(className);\n\n const canvas = this.canvas = document.createElement('canvas');\n canvas.classList.add(className + '-canvas');\n\n container.append(canvas);\n\n return container;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport liteMode from '../../helpers/liteMode';\nimport noop from '../../helpers/noop';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport rootScope from '../rootScope';\nimport lottieLoader, {LottieAssetName} from './lottieLoader';\nimport type RLottiePlayer from './rlottiePlayer';\nimport {RLottieColor} from './rlottiePlayer';\n\nexport type RLottieIconOptions = {\n width: number,\n height: number,\n container?: HTMLElement,\n skipAnimation?: boolean\n};\n\nexport type RLottieIconItemPartOptions = {\n startFrame: number,\n endFrame: number,\n name?: string\n};\n\nexport type RLottieIconItemOptions = {\n name: LottieAssetName,\n parts: RLottieIconItemPartOptions[],\n initFrame?: number,\n player?: RLottiePlayer,\n autoplay?: boolean,\n color?: RLottieColor,\n inverseColor?: RLottieColor,\n};\n\nexport class RLottieIconItemPart implements RLottieIconItemPartOptions {\n public startFrame: number;\n public endFrame: number;\n public name?: string;\n\n constructor(public item: RLottieIconItem, options: RLottieIconItemPartOptions) {\n safeAssign(this, options);\n }\n\n public play(callback?: () => void) {\n return this.item.playPart(this, callback);\n }\n}\n\n// export type RLottieIconItemPart = RLottieIconItemPartOptions;\n\nexport class RLottieIconItem implements RLottieIconItemOptions {\n public name: LottieAssetName;\n public parts: RLottieIconItemPart[];\n public player: RLottiePlayer;\n public initFrame: number;\n public autoplay: boolean;\n public color: RLottieColor;\n public inverseColor: RLottieColor;\n public loadPromise: Promise<void>;\n public onLoadForPart: () => void;\n public onLoadForColor: () => void;\n\n constructor(public icon: RLottieIcon, options: RLottieIconItemOptions) {\n this.autoplay = false;\n\n safeAssign(this, options);\n\n this.parts = this.parts.map((options) => this.createPart(options));\n }\n\n public load() {\n let loadPromise = this.loadPromise;\n if(loadPromise) {\n return loadPromise;\n }\n\n const {container, canvas, width, height} = this.icon;\n loadPromise = lottieLoader.loadAnimationAsAsset({\n container,\n canvas,\n width,\n height,\n group: 'none',\n loop: false,\n autoplay: this.autoplay ?? false,\n initFrame: this.initFrame,\n skipFirstFrameRendering: this.initFrame === undefined,\n color: this.color,\n inverseColor: this.inverseColor\n }, this.name).then((player) => {\n return lottieLoader.waitForFirstFrame(player);\n }).then((player) => {\n this.player = player;\n\n if(this.onLoadForColor) {\n this.onLoadForColor();\n this.onLoadForColor = undefined;\n }\n\n if(this.onLoadForPart) {\n this.onLoadForPart();\n this.onLoadForPart = undefined;\n }\n });\n\n this.loadPromise = loadPromise;\n this.icon.loadPromises.set(this.name, loadPromise);\n return loadPromise;\n }\n\n public createPart(options: RLottieIconItemPartOptions) {\n return new RLottieIconItemPart(this, options);\n }\n\n public getPart(index: string | number | RLottieIconItemPart) {\n if(index instanceof RLottieIconItemPart) return index;\n else if(typeof(index) === 'string') return this.parts.find((part) => part.name === index);\n else return this.parts[index];\n }\n\n public playPart(part: RLottieIconItemPart, callback?: () => void) {\n return this.icon.playPart(this, part, callback);\n }\n}\n\nexport default class RLottieIcon {\n public container: HTMLElement;\n public canvas: HTMLCanvasElement;\n public width: number;\n public height: number;\n\n protected items: Map<LottieAssetName, RLottieIconItem>;\n public loadPromises: Map<LottieAssetName, Promise<void>>;\n\n protected skipAnimation: boolean;\n\n constructor(options: RLottieIconOptions) {\n safeAssign(this, options);\n\n if(!this.container) this.container = document.createElement('div');\n this.container.classList.add('rlottie-icon');\n\n const {width, height} = this;\n this.container.style.width = width + 'px';\n this.container.style.height = height + 'px';\n\n const canvas = this.canvas = document.createElement('canvas');\n canvas.classList.add('rlottie');\n canvas.width = width;\n canvas.height = height;\n\n this.items = new Map();\n this.loadPromises = new Map();\n }\n\n public get loadPromise() {\n return Promise.all([...this.loadPromises.values()]).then(noop);\n }\n\n public getItem(name?: LottieAssetName): RLottieIconItem {\n return !name && this.items.size === 1 ? this.items.values().next().value : this.items.get(name);\n }\n\n public add(options: Omit<RLottieIconItemOptions, 'player'>) {\n const item = new RLottieIconItem(this, options);\n this.items.set(options.name, item);\n\n return item;\n }\n\n public playPart(item: RLottieIconItem, index: Parameters<RLottieIconItem['getPart']>[0], callback?: () => void) {\n if(!item.player) {\n item.onLoadForPart = () => {\n this.playPart(item, index, callback);\n };\n\n return;\n }\n\n const part = item.getPart(index);\n item.player.playPart({\n from: liteMode.isAvailable('animations') && !this.skipAnimation ? part.startFrame : part.endFrame,\n to: part.endFrame,\n callback\n });\n }\n\n /* public playToPart(item: RLottieIconItem, index: Parameters<RLottieIconItem['getPart']>[0], toEnd: boolean) {\n if(!item.player) return;\n const part = item.getPart(index);\n const toFrame = toEnd ? part.endFrame : part.startFrame;\n item.player.playToFrame({\n frame: toFrame\n });\n } */\n\n public static generateEqualParts(length: number, frameCount: number): RLottieIconItemPartOptions[] {\n return new Array(length).fill(0).map((_, idx) => {\n const startFrame = idx * frameCount;\n return {startFrame, endFrame: startFrame + frameCount - 1};\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport noop from '../helpers/noop';\nimport safeAssign from '../helpers/object/safeAssign';\nimport {LottieAssetName} from '../lib/rlottie/lottieLoader';\nimport RLottieIcon, {RLottieIconItemPartOptions, RLottieIconItemPart} from '../lib/rlottie/rlottieIcon';\nimport {RLottieColor} from '../lib/rlottie/rlottiePlayer';\n\nexport type SuperRLottieIconAddItemOptions = {name: LottieAssetName, parts: RLottieIconItemPartOptions};\nexport type SuperRLottieIconGetInfoResult = RLottieIconItemPart;\nexport class SuperRLottieIcon<Options extends {\n PartState: any,\n ColorState?: any,\n Items?: {\n name: string\n }[]\n}> extends RLottieIcon {\n protected getPart: (state: Options['PartState'], prevState?: Options['PartState']) => SuperRLottieIconGetInfoResult;\n protected getColor?: (state: Options['ColorState'], prevState?: Options['ColorState']) => RLottieColor;\n\n protected partState: Options['PartState'];\n protected colorState: Options['ColorState'];\n protected loaded: boolean;\n\n constructor(options: {\n width: number,\n height: number,\n skipAnimation?: boolean,\n getPart: (state: Options['PartState'], prevState?: Options['PartState']) => SuperRLottieIconGetInfoResult,\n getColor?: (state: Options['ColorState'], prevState?: Options['ColorState']) => RLottieColor,\n }) {\n super({\n width: options.width,\n height: options.height\n });\n\n safeAssign(this, options);\n\n // hook the first call\n /* const originalFunction = this.setState.bind(this);\n this.setState = (partState, colorState) => {\n this.setState = originalFunction;\n this.load(partState, colorState);\n return originalFunction(partState, colorState);\n }; */\n }\n\n public load(partState: Options['PartState'], colorState?: Options['ColorState']) {\n if(this.loaded) {\n return this.loadPromise;\n }\n\n this.loaded = true;\n this.partState = partState;\n this.colorState = colorState;\n\n const part = this.getPart(partState);\n const color = colorState !== undefined && this.getColor && this.getColor(colorState);\n\n const item = part.item;\n item.initFrame = part.endFrame;\n item.color = color;\n\n const promises = [...this.items.values()].map((item) => item.load());\n return Promise.all(promises).then(noop);\n }\n\n /**\n * Will redirect setting color state to part callback to synchronize the rendering\n */\n public setState(partState: Options['PartState'], colorState?: Options['ColorState'], partCallback?: () => void) {\n if(!this.loaded) this.load(partState, colorState);\n\n let changedPartState = false, changedColorState = false;\n if(partState !== undefined) changedPartState = this.setPartState(partState, colorState, partCallback);\n else if(colorState !== undefined) changedColorState = this.setColorState(colorState);\n\n return changedPartState || changedColorState;\n }\n\n public setPartState(state: Options['PartState'], colorState?: Options['ColorState'], callback?: () => void) {\n const {partState: prevState} = this;\n if(prevState === state) {\n return colorState !== undefined ? this.setColorState(colorState) : false;\n }\n\n if(colorState !== undefined) {\n this.setColorState(colorState, false);\n }\n\n this.partState = state;\n\n const part = this.getPart(state, prevState);\n part.play(callback);\n\n return true;\n }\n\n public setColorState(state: Options['ColorState'], renderIfPaused = true) {\n const {colorState: prevState} = this;\n if(prevState === state || !this.getColor) {\n return false;\n }\n\n this.colorState = state;\n\n const item = this.getItem();\n const color = this.getColor(state, prevState);\n const invoke = () => {\n item.player.setColor(color, renderIfPaused);\n };\n\n if(item.player) {\n invoke();\n } else {\n item.onLoadForColor = invoke;\n }\n\n return true;\n }\n\n public destroy() {\n this.items.forEach((item) => {\n item.loadPromise.then(() => {\n item.player.remove();\n });\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {RLottieIconItemPartOptions} from '../../lib/rlottie/rlottieIcon';\nimport {GROUP_CALL_MICROPHONE_BUTTON_STATE} from '.';\nimport {SuperRLottieIcon} from '../superIcon';\n\nexport default class GroupCallMicrophoneIcon extends SuperRLottieIcon<{\n PartState: GROUP_CALL_MICROPHONE_BUTTON_STATE\n}> {\n constructor() {\n super({\n width: 36,\n height: 36,\n getPart: (state, prevState) => {\n const states = GROUP_CALL_MICROPHONE_BUTTON_STATE;\n let partName: string;\n switch(state) {\n case states.HAND:\n partName = prevState === states.MUTED ? 'muted-to-hand' : 'unmuted-to-hand';\n break;\n case states.MUTED:\n partName = prevState === states.HAND ? 'hand-to-muted' : 'mute';\n break;\n case states.UNMUTED:\n partName = 'unmute';\n break;\n }\n\n return this.getItem().getPart(partName);\n }\n });\n\n const className = 'group-call-microphone-icon';\n this.container.classList.add(className + '-container');\n\n const parts: RLottieIconItemPartOptions[] = [{\n startFrame: 0,\n endFrame: 35,\n name: 'hand-to-muted'\n }, {\n startFrame: 36,\n endFrame: 68,\n name: 'unmute'\n }, {\n startFrame: 69,\n endFrame: 98,\n name: 'mute'\n }, {\n startFrame: 99,\n endFrame: 135,\n name: 'muted-to-hand'\n }, {\n startFrame: 136,\n endFrame: 172,\n name: 'unmuted-to-hand'\n }, {\n startFrame: 173,\n endFrame: 201,\n name: 'scheduled-crossing'\n }, {\n startFrame: 202,\n endFrame: 236,\n name: 'scheduled-to-muted'\n }, {\n startFrame: 237,\n endFrame: 273,\n name: 'scheduled-to-hand'\n }, {\n startFrame: 274,\n endFrame: 310,\n name: 'scheduled-crossed-to-hand'\n }, {\n startFrame: 311,\n endFrame: 343,\n name: 'scheduled-uncrossing'\n }, {\n startFrame: 344,\n endFrame: 375,\n name: 'scheduled-to-muted'\n }, {\n startFrame: 376,\n endFrame: 403,\n name: 'play-to-muted'\n }];\n\n this.add({\n name: 'voip_filled',\n parts\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport RLottieIcon from '../../lib/rlottie/rlottieIcon';\nimport {GROUP_CALL_PARTICIPANT_CLEARED_MUTED_STATE, GROUP_CALL_PARTICIPANT_MUTED_STATE, getColorByMutedState, clearMutedStateModifier} from '.';\nimport {SuperRLottieIcon} from '../superIcon';\n\nexport default class GroupCallParticipantMutedIcon extends SuperRLottieIcon<{\n PartState: GROUP_CALL_PARTICIPANT_CLEARED_MUTED_STATE,\n ColorState: GROUP_CALL_PARTICIPANT_MUTED_STATE\n}> {\n constructor(private colored: boolean) {\n super({\n width: 32,\n height: 32,\n getPart: (state, prevState) => {\n const states = GROUP_CALL_PARTICIPANT_MUTED_STATE;\n\n let index: number;\n switch(state) {\n case states.HAND:\n index = 3;\n break;\n case states.MUTED:\n index = prevState === states.HAND ? 0 : 2;\n break;\n case states.UNMUTED:\n index = 1;\n break;\n }\n\n return this.getItem().getPart(index);\n },\n getColor: colored ? (state, prevState) => {\n return getColorByMutedState(state);\n } : undefined\n });\n\n const className = 'group-call-participant-muted-icon';\n this.container.classList.add(className + '-container');\n\n const parts = RLottieIcon.generateEqualParts(4, 21);\n this.add({\n name: 'voice_outlined2',\n parts\n });\n }\n\n public setState(state: GROUP_CALL_PARTICIPANT_MUTED_STATE) {\n return super.setState(clearMutedStateModifier(state), state);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '../popups';\nimport {hexToRgb} from '../../helpers/color';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport customProperties from '../../helpers/dom/customProperties';\nimport {GroupCall, GroupCallParticipant} from '../../layer';\nimport type {AppChatsManager} from '../../lib/appManagers/appChatsManager';\nimport type {AppGroupCallsManager} from '../../lib/appManagers/appGroupCallsManager';\nimport type {AppPeersManager} from '../../lib/appManagers/appPeersManager';\nimport GROUP_CALL_STATE from '../../lib/calls/groupCallState';\nimport {RLottieColor} from '../../lib/rlottie/rlottiePlayer';\nimport rootScope from '../../lib/rootScope';\nimport ButtonIcon from '../buttonIcon';\nimport GroupCallMicrophoneIcon from './microphoneIcon';\nimport GroupCallParticipantsElement from './participants';\nimport GroupCallParticipantsVideoElement from './participantVideos';\nimport PopupPeer from '../popups/peer';\nimport GroupCallDescriptionElement from './description';\nimport GroupCallTitleElement from './title';\nimport {addFullScreenListener, cancelFullScreen, isFullScreen, requestFullScreen} from '../../helpers/dom/fullScreen';\nimport Scrollable from '../scrollable';\nimport {MovableState} from '../movableElement';\nimport animationIntersector from '../animationIntersector';\nimport {IS_APPLE_MOBILE} from '../../environment/userAgent';\nimport throttle from '../../helpers/schedulers/throttle';\nimport IS_SCREEN_SHARING_SUPPORTED from '../../environment/screenSharingSupport';\nimport GroupCallInstance from '../../lib/calls/groupCallInstance';\nimport makeButton from '../call/button';\nimport MovablePanel from '../../helpers/movablePanel';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport toggleClassName from '../../helpers/toggleClassName';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport themeController from '../../helpers/themeController';\nimport groupCallsController from '../../lib/calls/groupCallsController';\n\nexport enum GROUP_CALL_PARTICIPANT_MUTED_STATE {\n UNMUTED,\n MUTED,\n MUTED_FOR_ME,\n MUTED_BY_ADMIN,\n HAND\n}\n\nexport type GROUP_CALL_PARTICIPANT_CLEARED_MUTED_STATE = Exclude<GROUP_CALL_PARTICIPANT_MUTED_STATE, GROUP_CALL_PARTICIPANT_MUTED_STATE.MUTED_BY_ADMIN | GROUP_CALL_PARTICIPANT_MUTED_STATE.MUTED_FOR_ME>;\n\nexport function getGroupCallParticipantMutedState(participant: GroupCallParticipant) {\n const states = GROUP_CALL_PARTICIPANT_MUTED_STATE;\n if(participant.pFlags.muted_by_you) {\n return states.MUTED_FOR_ME;\n } else if(participant.raise_hand_rating !== undefined) {\n return states.HAND;\n } else if(participant.pFlags.muted) {\n return participant.pFlags.can_self_unmute ? states.MUTED : states.MUTED_BY_ADMIN;\n } else {\n return states.UNMUTED;\n }\n}\n\nexport function clearMutedStateModifier(state: GROUP_CALL_PARTICIPANT_MUTED_STATE): GROUP_CALL_PARTICIPANT_CLEARED_MUTED_STATE {\n const states = GROUP_CALL_PARTICIPANT_MUTED_STATE;\n switch(state) {\n case states.MUTED_BY_ADMIN:\n case states.MUTED_FOR_ME:\n return states.MUTED;\n default:\n return state;\n }\n}\n\nexport function getColorByMutedState(state: GROUP_CALL_PARTICIPANT_MUTED_STATE) {\n const states = GROUP_CALL_PARTICIPANT_MUTED_STATE;\n let colorStr: 'blue' | 'green' | 'secondary' | 'red';\n switch(state) {\n case states.HAND:\n colorStr = 'blue';\n break;\n case states.MUTED:\n case states.MUTED_FOR_ME:\n case states.MUTED_BY_ADMIN:\n colorStr = state === states.MUTED ? 'secondary' : 'red';\n break;\n case states.UNMUTED:\n colorStr = 'green';\n break;\n }\n\n const propertyValue = customProperties.getProperty('gc-' + colorStr + '-text-color');\n const color: RLottieColor = hexToRgb(propertyValue);\n\n return color;\n}\n\nexport enum GROUP_CALL_MICROPHONE_BUTTON_STATE {\n HAND,\n MUTED,\n UNMUTED,\n}\n\nexport function getGroupCallMicrophoneButtonState(groupCall: GroupCall.groupCall, participant: GroupCallParticipant) {\n const states = GROUP_CALL_MICROPHONE_BUTTON_STATE;\n if(!participant.pFlags.can_self_unmute) {\n return states.HAND;\n } else if(participant.pFlags.muted) {\n return states.MUTED\n } else {\n return states.UNMUTED;\n }\n}\n\nlet previousState: MovableState = {\n width: 420,\n height: 640\n};\n\nconst className = 'group-call';\n\nexport default class PopupGroupCall extends PopupElement {\n private instance: GroupCallInstance;\n private groupCallTitle: GroupCallTitleElement;\n private groupCallDescription: GroupCallDescriptionElement;\n private groupCallBodyHeaderDescription: GroupCallDescriptionElement;\n private groupCallParticipants: GroupCallParticipantsElement;\n private groupCallParticipantsVideo: GroupCallParticipantsVideoElement;\n private groupCallMicrophoneIcon: GroupCallMicrophoneIcon;\n private videosCount: number;\n private btnFullScreen: HTMLButtonElement;\n private btnExitFullScreen: HTMLButtonElement;\n private btnInvite: HTMLButtonElement;\n private btnShowColumn: HTMLButtonElement;\n private movablePanel: MovablePanel;\n private buttonsContainer: HTMLDivElement;\n private btnFullScreen2: HTMLButtonElement;\n private btnVideo: HTMLDivElement;\n private btnScreen: HTMLDivElement;\n\n constructor() {\n super('popup-group-call', {\n body: true,\n withoutOverlay: true,\n closable: true,\n title: true\n });\n\n this.videosCount = 0;\n this.container.classList.add(className, 'night');\n\n const instance = this.instance = groupCallsController.groupCall;\n const {listenerSetter} = this;\n\n if(!IS_APPLE_MOBILE) {\n const btnFullScreen = this.btnFullScreen = ButtonIcon('fullscreen');\n const btnFullScreen2 = this.btnFullScreen2 = ButtonIcon('fullscreen ' + className + '-cfs');\n const btnExitFullScreen = this.btnExitFullScreen = ButtonIcon('smallscreen');\n\n attachClickEvent(btnFullScreen, this.onFullScreenClick, {listenerSetter});\n attachClickEvent(btnFullScreen2, this.onFullScreenClick, {listenerSetter});\n\n attachClickEvent(btnExitFullScreen, () => {\n cancelFullScreen();\n }, {listenerSetter});\n\n addFullScreenListener(this.container, this.onFullScreenChange, listenerSetter);\n }\n\n const btnInvite = this.btnInvite = ButtonIcon('adduser');\n const btnShowColumn = this.btnShowColumn = ButtonIcon('rightpanel ' + className + '-only-big');\n\n attachClickEvent(btnShowColumn, this.toggleRightColumn, {listenerSetter});\n\n const headerInfo = document.createElement('div');\n headerInfo.classList.add(className + '-header-info');\n\n this.title.classList.add(className + '-header-title');\n\n const subtitle = document.createElement('div');\n subtitle.classList.add(className + '-header-subtitle');\n\n headerInfo.append(this.title, subtitle);\n\n this.header.classList.add(className + '-header');\n this.header.append(...[this.btnExitFullScreen, headerInfo/* , btnInvite */, this.btnFullScreen, btnShowColumn].filter(Boolean));\n\n const newHeader = this.header.cloneNode(false) as HTMLElement;\n const newHeaderInfo = headerInfo.cloneNode(false) as HTMLElement;\n const newHeaderTitle = this.title.cloneNode(false) as HTMLElement;\n\n newHeaderInfo.append(newHeaderTitle);\n\n const btnHideColumn = ButtonIcon('rightpanel');\n newHeader.append(...[btnHideColumn, newHeaderInfo, this.btnFullScreen2].filter(Boolean));\n\n attachClickEvent(btnHideColumn, this.toggleRightColumn, {listenerSetter});\n\n this.body.prepend(newHeader);\n\n const videosScrollable = new Scrollable(undefined);\n videosScrollable.container.classList.add('group-call-big-video-container');\n this.container.append(videosScrollable.container);\n\n this.groupCallTitle = new GroupCallTitleElement(this.title);\n this.groupCallDescription = new GroupCallDescriptionElement(subtitle);\n this.groupCallBodyHeaderDescription = new GroupCallDescriptionElement(newHeaderTitle);\n this.constructButtons();\n\n this.groupCallParticipantsVideo = new GroupCallParticipantsVideoElement({\n appendTo: videosScrollable.container,\n instance,\n listenerSetter,\n displayPinned: true,\n onLengthChange: (length) => {\n this.videosCount = length;\n this.toggleBigLayout();\n },\n managers: this.managers\n });\n this.groupCallParticipants = new GroupCallParticipantsElement({\n appendTo: this.body,\n instance,\n listenerSetter,\n managers: this.managers\n });\n\n this.movablePanel = new MovablePanel({\n listenerSetter,\n movableOptions: {\n minWidth: 400,\n minHeight: 480,\n element: this.element,\n verifyTouchTarget: (e) => {\n const target = e.target;\n if(findUpClassName(target, 'chatlist') ||\n findUpClassName(target, 'group-call-button') ||\n findUpClassName(target, 'btn-icon') ||\n findUpClassName(target, 'group-call-participants-video-container') ||\n isFullScreen()) {\n return false;\n }\n\n return true;\n }\n },\n onResize: () => this.toggleBigLayout(),\n previousState\n });\n\n listenerSetter.add(instance)('state', () => {\n this.updateInstance();\n });\n\n listenerSetter.add(rootScope)('group_call_update', (groupCall) => {\n if(this.instance?.id === groupCall.id) {\n this.updateInstance();\n }\n });\n\n listenerSetter.add(instance)('pinned', () => {\n this.setHasPinned();\n });\n\n listenerSetter.add(this.groupCallParticipantsVideo)('toggleControls', this.onToggleControls);\n\n this.addEventListener('close', () => {\n const {movablePanel} = this;\n previousState = movablePanel.state;\n\n this.groupCallParticipantsVideo.destroy();\n this.groupCallParticipants.destroy();\n this.groupCallMicrophoneIcon.destroy();\n\n movablePanel.destroy();\n });\n\n this.toggleRightColumn();\n this.onFullScreenChange();\n\n this.updateInstance();\n }\n\n private constructButtons() {\n const buttons = this.buttonsContainer = document.createElement('div');\n buttons.classList.add(className + '-buttons');\n\n const _makeButton = makeButton.bind(null, className, this.listenerSetter);\n\n const btnVideo = this.btnVideo = _makeButton({\n // text: 'VoiceChat.Video.Stream.Video',\n callback: this.onVideoClick,\n icon: 'videocamera_filled'\n });\n\n const btnScreen = this.btnScreen = _makeButton({\n // text: 'VoiceChat.Video.Stream.Screencast',\n callback: this.onScreenClick,\n icon: 'sharescreen_filled'\n });\n\n btnScreen.classList.toggle('hide', !IS_SCREEN_SHARING_SUPPORTED);\n\n const btnMute = _makeButton({\n noRipple: true,\n callback: throttle(this.onMuteClick, 600, true)\n });\n btnMute.classList.add(className + '-microphone-button');\n\n const microphoneIcon = this.groupCallMicrophoneIcon = new GroupCallMicrophoneIcon();\n btnMute.append(microphoneIcon.container);\n\n const btnMore = _makeButton({\n // text: 'VoiceChat.Video.Stream.More'\n icon: 'settings_filled'\n });\n\n btnMore.classList.add('btn-disabled');\n btnMore.classList.toggle('hide', !IS_SCREEN_SHARING_SUPPORTED);\n\n const btnLeave = _makeButton({\n // text: 'VoiceChat.Leave',\n isDanger: true,\n callback: this.onLeaveClick,\n icon: 'close'\n });\n\n buttons.append(btnVideo, btnScreen, btnMute, btnMore, btnLeave);\n\n this.container.append(buttons);\n }\n\n private onFullScreenClick = () => {\n requestFullScreen(this.container);\n };\n\n private onToggleControls = (show: boolean) => {\n this.container.classList.toggle('show-controls', show);\n this.buttonsContainer.classList.toggle('show-controls', show);\n };\n\n private toggleDisability = toggleClassName.bind(null, 'btn-disabled');\n\n private onVideoClick = () => {\n const toggle = this.toggleDisability([this.btnVideo], true);\n this.instance.toggleVideoSharing().finally(() => {\n toggle();\n });\n };\n\n private onScreenClick = () => {\n const toggle = this.toggleDisability([this.btnScreen], true);\n this.instance.toggleScreenSharing().finally(() => {\n toggle();\n });\n };\n\n private onMuteClick = () => {\n const participant = this.instance.participant;\n if(!participant.pFlags.can_self_unmute) {\n if(participant.raise_hand_rating === undefined) {\n this.instance.changeRaiseHand(true);\n }\n } else {\n this.instance.toggleMuted();\n }\n };\n\n private onLeaveClick = async() => {\n const hangUp = (discard: boolean) => {\n this.instance.hangUp(discard);\n };\n\n if(await this.managers.appChatsManager.hasRights(this.instance.chatId, 'manage_call')) {\n PopupElement.createPopup(PopupPeer, 'popup-end-video-chat', {\n titleLangKey: 'VoiceChat.End.Title',\n descriptionLangKey: 'VoiceChat.End.Text',\n checkboxes: [{\n text: 'VoiceChat.End.Third'\n }],\n buttons: [{\n langKey: 'VoiceChat.End.OK',\n callback: (checkboxes) => {\n hangUp(!!checkboxes.size);\n },\n isDanger: true\n }]\n }).show();\n } else {\n hangUp(false);\n }\n };\n\n public getContainer() {\n return this.container;\n }\n\n private onFullScreenChange = () => {\n this.toggleBigLayout();\n const isFull = isFullScreen();\n\n const {btnFullScreen, btnExitFullScreen} = this;\n\n const wasFullScreen = this.container.classList.contains('is-full-screen');\n this.container.classList.toggle('is-full-screen', isFull);\n btnFullScreen && btnFullScreen.classList.toggle('hide', isFull);\n btnExitFullScreen && btnExitFullScreen.classList.toggle('hide', !isFull);\n this.btnClose.classList.toggle('hide', isFull);\n\n if(isFull !== wasFullScreen) {\n animationIntersector.checkAnimations2(isFull);\n\n themeController.setThemeColor(isFull ? '#000000' : undefined);\n }\n };\n\n private toggleBigLayout = () => {\n const isFull = isFullScreen();\n const movable = this.movablePanel?.movable;\n const isBig = (isFull || !!(movable && movable.width >= 680)) && !!this.videosCount;\n\n /* if(!isBig && isFull) {\n cancelFullScreen();\n return;\n } */\n\n const wasBig = this.container.classList.contains('is-big-layout');\n let buttons: HTMLElement[];\n if(isBig && !wasBig) { // fix buttons transition to 0 opacity\n buttons = Array.from(this.buttonsContainer.children) as HTMLElement[];\n buttons.forEach((element) => {\n element.style.opacity = '0';\n });\n\n void this.buttonsContainer.offsetLeft;\n }\n\n this.container.classList.toggle('is-big-layout', isBig);\n this.btnInvite.classList.toggle('hide', isBig);\n this.btnShowColumn.classList.toggle('hide', !isBig);\n\n if(buttons) {\n // window.requestAnimationFrame(() => {\n buttons.forEach((element) => {\n element.style.opacity = '';\n });\n // });\n }\n };\n\n private toggleRightColumn = () => {\n this.container.classList.toggle('is-right-column-shown');\n };\n\n private setHasPinned() {\n this.container.classList.toggle('has-pinned', !!this.instance.pinnedSource);\n }\n\n private updateInstance() {\n if(this.instance.state === GROUP_CALL_STATE.CLOSED) {\n if(this.container.classList.contains('is-full-screen')) {\n cancelFullScreen();\n }\n\n this.hide();\n return;\n }\n\n const {participant, groupCall} = this.instance;\n if(!participant) {\n return;\n }\n\n this.setTitle();\n this.setDescription();\n this.setHasPinned();\n\n const microphoneButtonState = getGroupCallMicrophoneButtonState(groupCall as any, participant);\n this.container.dataset.micState = microphoneButtonState === GROUP_CALL_MICROPHONE_BUTTON_STATE.HAND ? 'hand' : (microphoneButtonState === GROUP_CALL_MICROPHONE_BUTTON_STATE.MUTED ? 'muted' : 'unmuted');\n this.groupCallMicrophoneIcon.setState(microphoneButtonState);\n }\n\n private setTitle() {\n this.groupCallTitle.update(this.instance);\n }\n\n private setDescription() {\n this.groupCallDescription.update(this.instance);\n this.groupCallBodyHeaderDescription.update(this.instance);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport {GroupCallParticipant} from '../../layer';\nimport {i18n} from '../../lib/langPack';\nimport {GROUP_CALL_PARTICIPANT_MUTED_STATE} from '.';\nimport {GroupCallParticipantVideoType} from './participantVideo';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\n\nconst className = 'group-call-participant-status';\nexport default class GroupCallParticipantStatusElement {\n public container: HTMLElement;\n\n constructor(private withIcons: GroupCallParticipantVideoType[]) {\n this.container = document.createElement('div');\n this.container.classList.add(className + '-container');\n }\n\n public setState(state: GROUP_CALL_PARTICIPANT_MUTED_STATE, participant: GroupCallParticipant) {\n const states = GROUP_CALL_PARTICIPANT_MUTED_STATE;\n const icons = this.withIcons.filter((type) => !!participant[type]).map((type) => {\n const iconClassName = `tgico-${type === 'presentation' ? 'listscreenshare' : 'videocamera_filled'}`;\n const i = document.createElement('i');\n i.classList.add(className + '-icon', className + '-icon-' + type, iconClassName);\n return i;\n });\n\n let element2: HTMLElement, actionClassName: string;\n if(state === states.MUTED_FOR_ME) {\n element2 = i18n('VoiceChat.Status.MutedForYou');\n actionClassName = 'is-muted';\n } else if(state === states.UNMUTED) {\n element2 = i18n('VoiceChat.Status.Speaking');\n actionClassName = 'is-speaking';\n } else if(state === states.HAND) {\n element2 = i18n('VoiceChat.Status.WantsSpeak');\n actionClassName = 'is-waiting';\n } else if(participant.about && !icons.length) {\n setInnerHTML(this.container, wrapEmojiText(participant.about));\n return;\n } else {\n element2 = i18n('VoiceChat.Status.Listening');\n actionClassName = 'is-listening';\n }\n\n const span = document.createElement('span');\n span.classList.add(className, actionClassName);\n span.append(...icons, element2);\n\n replaceContent(this.container, span);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport positionElementByIndex from '../../helpers/dom/positionElementByIndex';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport {fastRaf} from '../../helpers/schedulers';\nimport SortedList, {SortedElementBase} from '../../helpers/sortedList';\nimport appDialogsManager, {DialogDom, AppDialogsManager, DialogElementSize} from '../../lib/appManagers/appDialogsManager';\nimport {getGroupCallParticipantMutedState} from '.';\nimport GroupCallParticipantMutedIcon from './participantMutedIcon';\nimport GroupCallParticipantStatusElement from './participantStatus';\nimport type GroupCallInstance from '../../lib/calls/groupCallInstance';\nimport type LazyLoadQueue from '../lazyLoadQueue';\n\ninterface SortedParticipant extends SortedElementBase<PeerId> {\n dom: DialogDom,\n mutedIcon: GroupCallParticipantMutedIcon,\n status: GroupCallParticipantStatusElement\n}\n\nexport default class GroupCallParticipantsList extends SortedList<SortedParticipant> {\n public list: HTMLUListElement;\n\n protected lazyLoadQueue: LazyLoadQueue;\n protected avatarSize: DialogElementSize = 'abitbigger';\n protected rippleEnabled = true;\n protected autonomous = true;\n protected createChatListOptions: Parameters<AppDialogsManager['createChatList']>[0] = {/* new: true, */dialogSize: 72};\n\n constructor(private instance: GroupCallInstance) {\n super({\n getIndex: async(element) => (await this.instance.getParticipantByPeerId(element.id)).date,\n onDelete: (element) => {\n element.dom.listEl.remove();\n this.onElementDestroy(element);\n },\n onUpdate: async(element) => {\n const participant = await this.instance.getParticipantByPeerId(element.id);\n const state = getGroupCallParticipantMutedState(participant);\n\n element.mutedIcon.setState(state);\n element.status.setState(state, participant);\n },\n onSort: (element, idx) => {\n positionElementByIndex(element.dom.listEl, this.list, idx);\n },\n onElementCreate: (base) => {\n const {dom} = appDialogsManager.addDialogNew({\n peerId: base.id,\n container: false,\n avatarSize: this.avatarSize,\n autonomous: this.autonomous,\n meAsSaved: false,\n rippleEnabled: this.rippleEnabled,\n wrapOptions: {\n lazyLoadQueue: this.lazyLoadQueue\n }\n });\n\n const className = 'group-call-participant';\n dom.listEl.classList.add(className);\n\n const mutedIcon = new GroupCallParticipantMutedIcon(true);\n const status = new GroupCallParticipantStatusElement(['presentation', 'video']);\n replaceContent(dom.lastMessageSpan, status.container);\n dom.listEl.append(mutedIcon.container);\n (base as SortedParticipant).mutedIcon = mutedIcon;\n (base as SortedParticipant).status = status;\n\n /* instance.getParticipantByPeerId(base.id).then((participant) => {\n const mutedState = getGroupCallParticipantMutedState(participant);\n\n mutedIcon.setState(mutedState);\n status.setState(mutedState, participant);\n }); */\n\n (base as SortedParticipant).dom = dom;\n\n return base as SortedParticipant;\n },\n updateElementWith: fastRaf\n });\n\n this.list = appDialogsManager.createChatList(this.createChatListOptions);\n }\n\n public destroy() {\n this.elements.forEach((element) => {\n this.onElementDestroy(element);\n });\n }\n\n protected onElementDestroy(element: SortedParticipant) {\n element.mutedIcon.destroy();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {animate} from '../../helpers/animation';\n\nexport default function callVideoCanvasBlur(video: HTMLVideoElement) {\n const canvas = document.createElement('canvas');\n canvas.classList.add('call-video-blur');\n const size = 16;\n canvas.width = size;\n canvas.height = size;\n\n const ctx = canvas.getContext('2d', {alpha: false});\n ctx.filter = 'blur(2px)';\n const renderFrame = () => {\n ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, canvas.width, canvas.height);\n };\n\n animate(() => {\n renderFrame();\n return canvas.isConnected;\n });\n\n renderFrame();\n\n return canvas;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {GroupCallParticipant} from '../../layer';\nimport type {GroupCallOutputSource} from '../../lib/appManagers/appGroupCallsManager';\nimport {i18n} from '../../lib/langPack';\nimport PeerTitle from '../peerTitle';\nimport {getGroupCallParticipantMutedState} from '.';\nimport GroupCallParticipantMutedIcon from './participantMutedIcon';\nimport GroupCallParticipantStatusElement from './participantStatus';\nimport GroupCallInstance from '../../lib/calls/groupCallInstance';\nimport callVideoCanvasBlur from '../call/videoCanvasBlur';\nimport getPeerId from '../../lib/appManagers/utils/peers/getPeerId';\nimport {AppManagers} from '../../lib/appManagers/managers';\n\nconst className = 'group-call-participant-video';\n\nexport type GroupCallParticipantVideoType = 'video' | 'presentation';\nexport default class GroupCallParticipantVideoElement {\n public container: HTMLElement;\n private peerTitle: PeerTitle;\n private subtitle: HTMLElement;\n private info: HTMLElement;\n private left: HTMLElement;\n private right: HTMLElement;\n private header: HTMLElement;\n private groupCallParticipantMutedIcon: GroupCallParticipantMutedIcon;\n private groupCallParticipantStatus: GroupCallParticipantStatusElement;\n\n constructor(private managers: AppManagers, private instance: GroupCallInstance, public source: GroupCallOutputSource) {\n this.container = document.createElement('div');\n this.container.classList.add(className + '-container');\n\n this.info = document.createElement('div');\n this.info.classList.add(className + '-info');\n\n this.left = document.createElement('div');\n this.left.classList.add(className + '-info-left');\n\n this.right = document.createElement('div');\n this.right.classList.add(className + '-info-right');\n\n this.info.append(this.left, this.right);\n\n this.container.append(this.info);\n }\n\n public setPinned(value: boolean) {\n if(!value) {\n if(this.header) {\n this.header.remove();\n this.header = undefined;\n }\n\n return;\n } else if(this.header) {\n return;\n }\n\n // if(!this.header) {\n this.header = document.createElement('div');\n this.header.classList.add(className + '-header');\n\n const icon = document.createElement('i');\n icon.classList.add('group-call-pin-icon', 'tgico-pin');\n this.header.append(icon);\n\n this.container.append(this.header);\n // }\n\n // this.container.classList.toggle('is-pinned', value);\n }\n\n public setParticipant(participant: GroupCallParticipant, type: GroupCallParticipantVideoType, video: HTMLVideoElement) {\n let peerTitleElement: HTMLElement;\n if(participant.pFlags.self) {\n peerTitleElement = i18n('VoiceChat.Status.You');\n peerTitleElement.classList.add('peer-title');\n } else {\n this.peerTitle = new PeerTitle({\n peerId: getPeerId(participant.peer)\n });\n\n peerTitleElement = this.peerTitle.element;\n }\n\n this.groupCallParticipantMutedIcon = new GroupCallParticipantMutedIcon(false);\n this.groupCallParticipantStatus = new GroupCallParticipantStatusElement([type]);\n\n this.left.append(peerTitleElement, this.groupCallParticipantStatus.container);\n\n this.right.append(this.groupCallParticipantMutedIcon.container);\n\n video.classList.add(className, 'call-video');\n\n if(video.paused) {\n video.play();\n }\n\n const canvas = callVideoCanvasBlur(video);\n canvas.classList.add(className + '-blur');\n\n this.container.prepend(canvas, video);\n\n this.updateParticipant(participant);\n }\n\n public updateParticipant(participant: GroupCallParticipant) {\n const state = getGroupCallParticipantMutedState(participant);\n\n this.groupCallParticipantMutedIcon.setState(state);\n this.groupCallParticipantStatus.setState(state, participant);\n }\n\n public destroy() {\n this.groupCallParticipantMutedIcon.destroy();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport ControlsHover from '../../helpers/dom/controlsHover';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport {GroupCallParticipant} from '../../layer';\nimport {GroupCallOutputSource} from '../../lib/appManagers/appGroupCallsManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getPeerId from '../../lib/appManagers/utils/peers/getPeerId';\nimport GroupCallInstance from '../../lib/calls/groupCallInstance';\nimport rootScope from '../../lib/rootScope';\nimport GroupCallParticipantVideoElement, {GroupCallParticipantVideoType} from './participantVideo';\n\nexport default class GroupCallParticipantsVideoElement extends ControlsHover {\n private container: HTMLDivElement;\n private instance: GroupCallInstance;\n private participantsElements: Map<PeerId, Map<GroupCallParticipantVideoType, GroupCallParticipantVideoElement>>;\n private displayPinned: boolean;\n private containers: Map<HTMLElement, GroupCallParticipantVideoElement>;\n private onLengthChange: (length: number) => void;\n private managers: AppManagers;\n\n constructor(options: {\n appendTo: HTMLElement,\n instance: GroupCallInstance,\n listenerSetter: ListenerSetter,\n displayPinned: boolean,\n onLengthChange?: GroupCallParticipantsVideoElement['onLengthChange'],\n managers: AppManagers\n }) {\n super();\n safeAssign(this, options);\n\n const className = 'group-call-participants-video';\n const container = this.container = document.createElement('div');\n this.container.classList.add(className + '-container');\n\n options.appendTo.append(container);\n\n this.participantsElements = new Map();\n this.containers = new Map();\n\n const {listenerSetter} = this;\n\n listenerSetter.add(rootScope)('group_call_participant', ({groupCallId, participant}) => {\n if(this.instance.id === groupCallId) {\n this.updateParticipant(participant);\n }\n });\n\n listenerSetter.add(this.instance)('pinned', (source) => {\n this.participantsElements.forEach((map) => {\n map.forEach((element) => {\n this.setElementDisplay(element, source);\n });\n });\n });\n\n attachClickEvent(this.container, (e) => {\n const container = findUpClassName(e.target, 'group-call-participant-video-container');\n if(!container) {\n return;\n }\n\n const element = this.containers.get(container);\n if(this.instance.pinnedSource === element.source) {\n this.instance.unpinAll();\n return;\n }\n\n this.instance.pinSource(element.source);\n }, {listenerSetter});\n\n this.setInstance(this.instance);\n\n this.setup({\n element: container,\n listenerSetter: listenerSetter,\n showOnLeaveToClassName: 'group-call-buttons'\n });\n }\n\n private shouldDisplayElement(element: GroupCallParticipantVideoElement, pinnedSource: GroupCallOutputSource) {\n return this.displayPinned ? !pinnedSource || element.source === pinnedSource : pinnedSource && element.source !== pinnedSource;\n }\n\n private setElementDisplay(element: GroupCallParticipantVideoElement, pinnedSource: GroupCallOutputSource) {\n const shouldDisplay = this.shouldDisplayElement(element, pinnedSource);\n element.container.classList.toggle('video-hidden', !shouldDisplay);\n\n const isPinned = element.source === pinnedSource;\n element.setPinned(isPinned);\n }\n\n private updateParticipant(participant: GroupCallParticipant) {\n const peerId = getPeerId(participant.peer);\n const types: GroupCallParticipantVideoType[] = ['video', 'presentation'];\n const hasAnyVideo = types.some((type) => !!participant[type]);\n let participantElements = this.participantsElements.get(peerId);\n if(!hasAnyVideo && !participantElements) {\n return;\n }\n\n if(!participantElements) {\n this.participantsElements.set(peerId, participantElements = new Map());\n }\n\n types.forEach((type) => {\n let element = participantElements.get(type);\n const participantVideo = participant[type];\n if(!!participantVideo === !!element) {\n if(element) {\n element.updateParticipant(participant);\n }\n\n return;\n }\n\n if(participantVideo) {\n const result = this.instance.getVideoElementFromParticipantByType(participant, type);\n if(!result) {\n return;\n }\n\n const {video, source} = result;\n\n element = new GroupCallParticipantVideoElement(this.managers, this.instance, source);\n\n this.containers.set(element.container, element);\n\n this.setElementDisplay(element, this.instance.pinnedSource);\n participantElements.set(type, element);\n element.setParticipant(participant, type, video);\n\n this.container.prepend(element.container);\n } else {\n participantElements.delete(type);\n element.container.remove();\n\n if(!participantElements.size) {\n this.participantsElements.delete(peerId);\n this.containers.delete(element.container);\n element.destroy();\n }\n }\n\n this._onLengthChange();\n });\n }\n\n private _onLengthChange() {\n const length = this.container.childElementCount;\n this.container.dataset.length = '' + length;\n this.container.dataset.layout = length <= 2 ? '1' : (length === 3 ? '3' : '4');\n\n this.onLengthChange && this.onLengthChange(length);\n }\n\n public async setInstance(instance: GroupCallInstance) {\n (await instance.participants).forEach((participant) => {\n this.updateParticipant(participant);\n });\n }\n\n public destroy() {\n this.containers.forEach((element) => {\n element.destroy();\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupGroupCall from '.';\nimport filterAsync from '../../helpers/array/filterAsync';\nimport contextMenuController from '../../helpers/contextMenuController';\nimport {attachContextMenuListener} from '../../helpers/dom/attachContextMenuListener';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport {addFullScreenListener, isFullScreen} from '../../helpers/dom/fullScreen';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport noop from '../../helpers/noop';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport positionMenu from '../../helpers/positionMenu';\nimport ScrollableLoader from '../../helpers/scrollableLoader';\nimport {GroupCallParticipant} from '../../layer';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport getPeerId from '../../lib/appManagers/utils/peers/getPeerId';\nimport GroupCallInstance from '../../lib/calls/groupCallInstance';\nimport rootScope from '../../lib/rootScope';\nimport {ButtonMenuItemOptions, ButtonMenuSync} from '../buttonMenu';\nimport confirmationPopup from '../confirmationPopup';\nimport PeerTitle from '../peerTitle';\nimport PopupElement from '../popups';\nimport Scrollable from '../scrollable';\nimport GroupCallParticipantsList from './participantsList';\nimport GroupCallParticipantsVideoElement from './participantVideos';\n\nexport class GroupCallParticipantContextMenu {\n private buttons: (ButtonMenuItemOptions & {verify: (peerId: PeerId) => boolean | Promise<boolean>})[];\n private element: HTMLElement;\n private chatId: ChatId;\n private targetPeerId: PeerId;\n private participant: GroupCallParticipant;\n private instance: GroupCallInstance;\n private canManageCall: boolean;\n private managers: AppManagers;\n\n constructor(options: {\n listenerSetter: ListenerSetter,\n onContextElement: HTMLElement,\n managers: AppManagers,\n instance: GroupCallInstance,\n }) {\n this.buttons = [{\n icon: 'gc_microphoneoff',\n text: 'VoiceChat.MutePeer',\n verify: () => this.canManageCall && this.participant.pFlags.can_self_unmute,\n onClick: () => this.toggleParticipantMuted(true)\n }, {\n icon: 'gc_microphone',\n text: 'VoiceChat.UnmutePeer',\n verify: () => this.canManageCall && !this.participant.pFlags.can_self_unmute,\n onClick: () => this.toggleParticipantMuted(false)\n }, {\n icon: 'gc_microphoneoff',\n text: 'VoiceChat.MuteForMe',\n verify: () => !this.canManageCall && !this.participant.pFlags.muted_by_you,\n onClick: () => this.toggleParticipantMuted(true)\n }, {\n icon: 'gc_microphone',\n text: 'VoiceChat.UnmuteForMe',\n verify: () => !this.canManageCall && this.participant.pFlags.muted_by_you,\n onClick: () => this.toggleParticipantMuted(false)\n }, {\n icon: 'newprivate',\n text: 'VoiceChat.OpenProfile',\n verify: () => true,\n onClick: this.onOpenProfileClick\n }, {\n icon: 'deleteuser danger',\n text: 'VoiceChat.RemovePeer',\n verify: () => this.managers.appChatsManager.hasRights(this.chatId, 'ban_users'),\n onClick: async() => {\n confirmationPopup({\n peerId: this.targetPeerId,\n title: new PeerTitle({peerId: this.targetPeerId}).element,\n descriptionLangKey: await this.managers.appChatsManager.isBroadcast(this.chatId) ? 'VoiceChat.RemovePeer.Confirm.Channel' : 'VoiceChat.RemovePeer.Confirm',\n descriptionLangArgs: [new PeerTitle({peerId: this.targetPeerId}).element],\n button: {\n langKey: 'VoiceChat.RemovePeer.Confirm.OK',\n isDanger: true\n }\n }).then(() => {\n this.managers.appChatsManager.kickFromChat(this.chatId, this.targetPeerId);\n }, noop);\n }\n }];\n\n const {listenerSetter} = options;\n this.managers = options.managers;\n this.instance = options.instance;\n this.chatId = this.instance.chatId;\n\n this.element = ButtonMenuSync({buttons: this.buttons, listenerSetter});\n this.element.classList.add('group-call-participant-menu', 'night');\n\n attachContextMenuListener({\n element: options.onContextElement,\n callback: async(e) => {\n const li = findUpClassName(e.target, 'group-call-participant');\n if(!li) {\n return;\n }\n\n if(this.element.parentElement !== appendTo) {\n appendTo.append(this.element);\n }\n\n cancelEvent(e);\n\n const peerId = this.targetPeerId = li.dataset.peerId.toPeerId();\n this.participant = await this.instance.getParticipantByPeerId(peerId);\n if(this.participant.pFlags.self) {\n return;\n }\n\n this.canManageCall = await this.managers.appChatsManager.hasRights(this.chatId, 'manage_call');\n\n await filterAsync(this.buttons, async(button) => {\n const good = await button.verify(peerId);\n button.element.classList.toggle('hide', !good);\n return good;\n });\n\n positionMenu((e as TouchEvent).touches ? (e as TouchEvent).touches[0] : e as MouseEvent, this.element, 'right');\n contextMenuController.openBtnMenu(this.element);\n },\n listenerSetter\n });\n\n listenerSetter.add(rootScope)('group_call_participant', ({groupCallId, participant}) => {\n if(this.instance.id === groupCallId) {\n const peerId = getPeerId(participant.peer);\n if(this.targetPeerId === peerId) {\n contextMenuController.close();\n }\n }\n });\n\n let appendTo: HTMLElement = document.body;\n addFullScreenListener(document.body, () => {\n const isFull = isFullScreen();\n appendTo = isFull ? PopupElement.getPopups(PopupGroupCall)[0].getContainer(): document.body;\n\n if(!isFull) {\n contextMenuController.close();\n }\n }, listenerSetter);\n }\n\n private onOpenProfileClick = () => {\n const popup = PopupElement.getPopups(PopupGroupCall)[0];\n if(popup) {\n popup.hide();\n }\n\n appImManager.setInnerPeer({peerId: this.targetPeerId});\n };\n\n private toggleParticipantMuted = (muted: boolean) => {\n this.instance.editParticipant(this.participant, {\n muted\n });\n };\n};\n\nexport default class GroupCallParticipantsElement {\n private container: HTMLDivElement;\n private sortedList: GroupCallParticipantsList;\n private instance: GroupCallInstance;\n private listenerSetter: ListenerSetter;\n private groupCallParticipantsVideo: GroupCallParticipantsVideoElement;\n private contextMenu: GroupCallParticipantContextMenu;\n private managers: AppManagers;\n\n constructor(options: {\n appendTo: HTMLElement,\n instance: GroupCallInstance,\n listenerSetter: ListenerSetter,\n managers: AppManagers\n }) {\n safeAssign(this, options);\n\n const className = 'group-call-participants';\n\n const scrollable = new Scrollable(undefined);\n scrollable.container.classList.add(className + '-scrollable');\n\n const container = this.container = document.createElement('div');\n container.classList.add(className);\n\n // const invite = Button(`btn-primary btn-transparent ${className}-invite`, {icon: 'adduser', text: 'VoiceChat.Invite.InviteMembers'});\n\n const sortedList = this.sortedList = new GroupCallParticipantsList(this.instance);\n\n const {instance, listenerSetter} = this;\n this.contextMenu = new GroupCallParticipantContextMenu({\n ...options,\n onContextElement: sortedList.list,\n listenerSetter,\n instance\n });\n\n this.groupCallParticipantsVideo = new GroupCallParticipantsVideoElement({\n ...options,\n appendTo: scrollable.container,\n displayPinned: false\n });\n\n scrollable.append(/* invite, */sortedList.list);\n container.append(scrollable.container);\n\n options.appendTo.append(container);\n\n listenerSetter.add(rootScope)('group_call_participant', ({groupCallId, participant}) => {\n if(this.instance.id === groupCallId) {\n this.updateParticipant(participant);\n }\n });\n\n const scrollableLoader = new ScrollableLoader({\n scrollable,\n getPromise: () => {\n return this.managers.appGroupCallsManager.getGroupCallParticipants(this.instance.id).then(({participants, isEnd}) => {\n participants.forEach((participant) => {\n this.updateParticipant(participant);\n });\n\n return isEnd;\n });\n }\n });\n\n this.setInstance(instance);\n }\n\n private updateParticipant(participant: GroupCallParticipant) {\n const peerId = getPeerId(participant.peer);\n const has = this.sortedList.has(peerId);\n if(participant.pFlags.left) {\n if(has) {\n this.sortedList.delete(peerId);\n }\n\n return;\n }\n\n if(!has) {\n this.sortedList.add(peerId);\n return;\n }\n\n this.sortedList.update(peerId);\n }\n\n public async setInstance(instance: GroupCallInstance) {\n // @ts-ignore\n /* const users = appUsersManager.users;\n for(const userId in users) {\n const participant: GroupCallParticipant = {\n _: 'groupCallParticipant',\n date: 0,\n peer: {_: 'peerUser', user_id: userId.toPeerId()},\n pFlags: {\n muted: true\n },\n source: 1\n };\n\n instance.participants.set(userId.toPeerId(), participant);\n this.updateParticipant(participant);\n } */\n const participants = await instance.participants;\n participants.forEach((participant) => {\n this.updateParticipant(participant);\n });\n }\n\n public destroy() {\n this.sortedList.destroy();\n this.groupCallParticipantsVideo.destroy();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {GroupCall} from '../../layer';\nimport GroupCallInstance from '../../lib/calls/groupCallInstance';\nimport GROUP_CALL_STATE from '../../lib/calls/groupCallState';\nimport I18n, {LangPackKey, FormatterArguments} from '../../lib/langPack';\n\nexport default class GroupCallDescriptionElement {\n private descriptionIntl: I18n.IntlElement;\n\n constructor(private appendTo: HTMLElement) {\n this.descriptionIntl = new I18n.IntlElement({\n key: 'VoiceChat.Status.Connecting'\n });\n\n this.descriptionIntl.element.classList.add('group-call-description');\n }\n\n public detach() {\n this.descriptionIntl.element.remove();\n }\n\n public update(instance: GroupCallInstance) {\n const {state} = instance;\n\n let key: LangPackKey, args: FormatterArguments;\n if(state === GROUP_CALL_STATE.CONNECTING) {\n key = 'VoiceChat.Status.Connecting';\n } else {\n key = 'VoiceChat.Status.Members';\n args = [(instance.groupCall as GroupCall.groupCall).participants_count];\n }\n\n const {descriptionIntl} = this;\n descriptionIntl.compareAndUpdate({\n key,\n args\n });\n\n if(!this.descriptionIntl.element.parentElement) {\n this.appendTo.append(this.descriptionIntl.element);\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport {GroupCall} from '../../layer';\nimport GroupCallInstance from '../../lib/calls/groupCallInstance';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport PeerTitle from '../peerTitle';\n\nexport default class GroupCallTitleElement {\n private peerTitle: PeerTitle;\n\n constructor(private appendTo: HTMLElement) {\n this.peerTitle = new PeerTitle({peerId: 0});\n }\n\n public update(instance: GroupCallInstance) {\n const {peerTitle, appendTo} = this;\n const groupCall = instance.groupCall as GroupCall.groupCall;\n const peerId = instance.chatId.toPeerId(true);\n if(groupCall.title) {\n setInnerHTML(appendTo, wrapEmojiText(groupCall.title));\n } else {\n if(peerTitle.options.peerId !== peerId) {\n peerTitle.options.peerId = peerId;\n peerTitle.update();\n }\n\n if(peerTitle.element.parentElement !== appendTo) {\n appendTo.append(peerTitle.element);\n }\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport ListenerSetter from '../../helpers/listenerSetter';\nimport {i18n, LangPackKey} from '../../lib/langPack';\nimport ripple from '../ripple';\n\nexport default function makeButton(className: string, listenerSetter: ListenerSetter, options: {\n text?: LangPackKey | HTMLElement,\n isDanger?: boolean,\n noRipple?: boolean,\n callback?: () => void,\n icon?: string,\n isConfirm?: boolean,\n}) {\n const _className = className + '-button';\n const buttonDiv = document.createElement('div');\n buttonDiv.classList.add(_className, 'call-button', 'rp-overflow');\n\n if(options.icon) {\n buttonDiv.classList.add('tgico-' + options.icon);\n }\n\n if(!options.noRipple) {\n ripple(buttonDiv);\n }\n\n if(options.isDanger) {\n buttonDiv.classList.add(_className + '-red');\n }\n\n if(options.isConfirm) {\n buttonDiv.classList.add(_className + '-green');\n }\n\n if(options.callback) {\n attachClickEvent(buttonDiv, options.callback, {listenerSetter});\n }\n\n let ret = buttonDiv;\n if(options.text) {\n const div = document.createElement('div');\n div.classList.add(_className + '-container', 'call-button-container');\n\n const textEl = typeof(options.text) === 'string' ? i18n(options.text) : options.text;\n textEl.classList.add(_className + '-text', 'call-button-text');\n\n div.append(buttonDiv, textEl);\n\n ret = div;\n }\n\n return ret;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport findUpClassName from '../helpers/dom/findUpClassName';\nimport EventListenerBase from '../helpers/eventListenerBase';\nimport mediaSizes from '../helpers/mediaSizes';\nimport clamp from '../helpers/number/clamp';\nimport safeAssign from '../helpers/object/safeAssign';\nimport windowSize from '../helpers/windowSize';\nimport SwipeHandler from './swipeHandler';\n\ntype ResizeSide = 'n' | 'e' | 's' | 'w' | 'ne' | 'se' | 'sw' | 'nw';\nexport type MovableState = {\n top?: number;\n left?: number;\n width: number;\n height: number;\n};\n\nconst className = 'movable-element';\nconst resizeHandlerClassName = className + '-resize-handler';\n\nexport type MovableElementOptions = {\n minWidth: MovableElement['minWidth'],\n minHeight: MovableElement['minHeight'],\n element: MovableElement['element'],\n verifyTouchTarget?: MovableElement['verifyTouchTarget']\n};\n\nexport default class MovableElement extends EventListenerBase<{\n resize: () => void\n}> {\n private minWidth: number;\n private minHeight: number;\n private element: HTMLElement;\n private verifyTouchTarget: SwipeHandler['verifyTouchTarget'];\n\n private top: number;\n private left: number;\n private _width: number;\n private _height: number;\n\n private swipeHandler: SwipeHandler;\n private handlers: HTMLElement[];\n\n constructor(options: MovableElementOptions) {\n super(true);\n safeAssign(this, options);\n\n this.top = this.left = this.width = this.height = 0;\n this.element.classList.add(className);\n\n this.addResizeHandlers();\n this.setSwipeHandler();\n\n mediaSizes.addEventListener('resize', this.onResize);\n }\n\n private onResize = () => {\n this.fixDimensions();\n this.fixPosition();\n this.setPosition();\n };\n\n public destroyElements() {\n this.element.classList.remove(className);\n\n if(this.handlers) {\n this.handlers.forEach((handler) => {\n handler.remove();\n });\n }\n }\n\n public destroy() {\n mediaSizes.removeEventListener('resize', this.onResize);\n this.swipeHandler.removeListeners();\n }\n\n private addResizeHandlers() {\n const sides: ResizeSide[] = ['n', 'e', 's', 'w', 'ne', 'se', 'sw', 'nw'];\n this.handlers = sides.map((side) => {\n const div = document.createElement('div');\n div.dataset.side = side;\n div.classList.add(resizeHandlerClassName, resizeHandlerClassName + '-side-' + side);\n this.element.append(div);\n return div;\n });\n }\n\n private setSwipeHandler() {\n let startTop: number, startLeft: number, startWidth: number, startHeight: number, resizingSide: ResizeSide;\n const swipeHandler = this.swipeHandler = new SwipeHandler({\n element: this.element,\n onSwipe: (xDiff, yDiff, e) => {\n // console.log(xDiff, yDiff, e);\n\n if(resizingSide) {\n if(resizingSide.includes('e') || resizingSide.includes('w')) {\n const isEnlarging = resizingSide.includes('e') && xDiff > 0 || resizingSide.includes('w') && xDiff < 0;\n const resizeDiff = Math.abs(xDiff) * (isEnlarging ? 1 : -1);\n\n const maxPossible = resizingSide.includes('e') ? windowSize.width - startLeft : startWidth + startLeft;\n this.width = Math.min(maxPossible, startWidth + resizeDiff);\n }\n\n if(resizingSide.includes('n') || resizingSide.includes('s')) {\n const isEnlarging = resizingSide.includes('s') && yDiff > 0 || resizingSide.includes('n') && yDiff < 0;\n const resizeDiff = Math.abs(yDiff) * (isEnlarging ? 1 : -1);\n\n const maxPossible = resizingSide.includes('s') ? windowSize.height - startTop : startHeight + startTop;\n this.height = Math.min(maxPossible, startHeight + resizeDiff);\n }\n\n this.fixDimensions();\n\n if(resizingSide.includes('w')) {\n this.left = Math.min(startLeft + startWidth - this.minWidth, startLeft + xDiff);\n }\n\n if(resizingSide.includes('n')) {\n this.top = Math.min(startTop + startHeight - this.minHeight, startTop + yDiff);\n }\n } else {\n this.top = startTop + yDiff;\n this.left = startLeft + xDiff;\n }\n\n this.fixPosition();\n this.setPosition();\n },\n verifyTouchTarget: (e) => {\n const target = e.target;\n if(this.verifyTouchTarget && !this.verifyTouchTarget(e)) {\n return false;\n }\n\n const resizeHandler = findUpClassName(target, resizeHandlerClassName);\n if(resizeHandler) {\n resizingSide = resizeHandler.dataset.side as ResizeSide;\n swipeHandler.setCursor('');\n } else {\n resizingSide = undefined;\n swipeHandler.setCursor('grabbing');\n }\n\n return true;\n },\n onFirstSwipe: () => {\n startTop = this.top;\n startLeft = this.left;\n startWidth = this.width;\n startHeight = this.height;\n }\n });\n }\n\n public setPositionToCenter() {\n this.top = (windowSize.height / 2) - (this.height / 2);\n this.left = (windowSize.width / 2) - (this.width / 2);\n this.setPosition();\n }\n\n private fixDimensions() {\n this.width = clamp(this.width, this.minWidth, windowSize.width);\n this.height = clamp(this.height, this.minHeight, windowSize.height);\n }\n\n private fixPosition() {\n this.top = clamp(this.top, 0, windowSize.height - this.height);\n this.left = clamp(this.left, 0, windowSize.width - this.width);\n }\n\n private setPosition() {\n this.element.style.top = this.top + 'px';\n this.element.style.left = this.left + 'px';\n this.element.style.right = 'auto';\n this.element.style.bottom = 'auto';\n this.element.style.width = this.width + 'px';\n this.element.style.height = this.height + 'px';\n\n this.dispatchEvent('resize');\n }\n\n public get width() {\n return this._width;\n }\n\n public get height() {\n return this._height;\n }\n\n private set width(value: number) {\n this._width = value;\n }\n\n private set height(value: number) {\n this._height = value;\n }\n\n public get state(): MovableState {\n const {top, left, width, height} = this;\n return {\n top,\n left,\n width,\n height\n };\n }\n\n public set state(state: MovableState) {\n const {top, left, width, height} = state;\n this.top = top;\n this.left = left;\n this.width = width;\n this.height = height;\n this.onResize();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport MovableElement, {MovableElementOptions, MovableState} from '../components/movableElement';\nimport IS_TOUCH_SUPPORTED from '../environment/touchSupport';\nimport ListenerSetter from './listenerSetter';\nimport mediaSizes, {ScreenSize} from './mediaSizes';\nimport safeAssign from './object/safeAssign';\n\nexport default class MovablePanel {\n #movable: MovableElement;\n private listenerSetter: ListenerSetter;\n private previousState: MovableState;\n private onResize: () => void;\n private movableOptions: MovableElementOptions;\n\n constructor(options: {\n listenerSetter: ListenerSetter,\n previousState: MovableState,\n onResize?: () => void,\n movableOptions: MovableElementOptions\n }) {\n safeAssign(this, options);\n\n this.toggleMovable(!IS_TOUCH_SUPPORTED);\n\n this.listenerSetter.add(mediaSizes)('changeScreen', (from, to) => {\n if(to === ScreenSize.mobile || from === ScreenSize.mobile) {\n this.toggleMovable(!IS_TOUCH_SUPPORTED);\n }\n });\n }\n\n public destroy() {\n const movable = this.movable;\n if(movable) {\n movable.destroy();\n }\n }\n\n public get movable() {\n return this.#movable;\n }\n\n public get state() {\n return this.movable ? this.movable.state : this.previousState;\n }\n\n public set state(state: MovableState) {\n this.previousState = state;\n }\n\n private toggleMovable(enabled: boolean) {\n let {movable} = this;\n if(enabled) {\n if(movable) {\n return;\n }\n\n movable = this.#movable = new MovableElement(this.movableOptions);\n\n movable.state = this.previousState;\n if(this.previousState.top === undefined) {\n movable.setPositionToCenter();\n }\n\n if(this.onResize) {\n this.listenerSetter.add(movable)('resize', this.onResize);\n }\n } else {\n if(!movable) {\n return;\n }\n\n this.previousState = movable.state;\n movable.destroyElements();\n movable.destroy();\n this.#movable = undefined;\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function toggleClassName(className: string, elements: HTMLElement[], disable: boolean) {\n elements.forEach((element) => {\n element.classList.toggle(className, disable);\n });\n\n return () => toggleClassName(className, elements, !disable);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport toHHMMSS from '../../helpers/string/toHHMMSS';\nimport CALL_STATE from '../../lib/calls/callState';\nimport {i18n, LangPackKey} from '../../lib/langPack';\n\nexport default class CallDescriptionElement {\n private container: HTMLElement;\n private state: CALL_STATE;\n private interval: number;\n\n constructor(private appendTo: HTMLElement) {\n this.container = document.createElement('div');\n this.container.classList.add('call-description');\n }\n\n public detach() {\n if(this.interval !== undefined) {\n clearInterval(this.interval);\n this.interval = undefined;\n }\n\n this.container.remove();\n this.state = undefined;\n }\n\n public update(instance: any) {\n const {connectionState} = instance;\n\n if(this.state === connectionState) {\n return;\n }\n\n this.state = connectionState;\n\n let element: HTMLElement;\n if(connectionState === CALL_STATE.CONNECTED) {\n element = document.createElement('span');\n element.classList.add('call-description-duration');\n\n const setTime = () => {\n element.innerText = toHHMMSS(instance.duration, true);\n };\n\n this.interval = window.setInterval(setTime, 1000);\n setTime();\n } else {\n let langPackKey: LangPackKey;\n switch(connectionState) {\n case CALL_STATE.PENDING:\n langPackKey = instance.isOutgoing ? 'Call.StatusRinging' : 'Call.StatusCalling';\n break;\n case CALL_STATE.REQUESTING:\n langPackKey = 'Call.StatusRequesting';\n break;\n case CALL_STATE.EXCHANGING_KEYS:\n langPackKey = 'VoipExchangingKeys';\n break;\n case CALL_STATE.CLOSED:\n langPackKey = instance.connectedAt !== undefined ? 'Call.StatusEnded' : 'Call.StatusFailed';\n break;\n default:\n langPackKey = 'Call.StatusConnecting';\n break;\n }\n\n element = i18n(langPackKey);\n if(this.interval !== undefined) {\n clearInterval(this.interval);\n this.interval = undefined;\n }\n }\n\n this.container.classList.toggle('has-duration', connectionState === CALL_STATE.CONNECTED);\n replaceContent(this.container, element);\n\n if(!this.container.parentElement) {\n this.appendTo.append(this.container);\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {SuperRLottieIcon} from '../superIcon';\n\nexport default class GroupCallMicrophoneIconMini extends SuperRLottieIcon<{\n PartState: boolean,\n ColorState: boolean,\n Items: {\n name: 'voice_mini'\n }[]\n}> {\n constructor(colored?: boolean, skipAnimation?: boolean) {\n super({\n width: 36,\n height: 36,\n getPart: (state) => {\n return this.getItem().getPart(state ? 'unmute' : 'mute');\n },\n getColor: colored ? (state) => {\n return state ? [255, 255, 255] : [158, 158, 158];\n } : undefined,\n skipAnimation\n });\n\n this.add({\n name: 'voice_mini',\n parts: [{\n startFrame: 0,\n endFrame: 35,\n name: 'hand-to-muted'\n }, {\n startFrame: 36,\n endFrame: 68,\n name: 'unmute'\n }, {\n startFrame: 69,\n endFrame: 98,\n name: 'mute'\n }, {\n startFrame: 99,\n endFrame: 135,\n name: 'muted-to-hand'\n }, {\n startFrame: 136,\n endFrame: 171,\n name: 'unmuted-to-hand'\n }]\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport IS_SCREEN_SHARING_SUPPORTED from '../../environment/screenSharingSupport';\nimport {IS_MOBILE} from '../../environment/userAgent';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport ControlsHover from '../../helpers/dom/controlsHover';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport {addFullScreenListener, cancelFullScreen, isFullScreen, requestFullScreen} from '../../helpers/dom/fullScreen';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport MovablePanel from '../../helpers/movablePanel';\nimport onMediaLoad from '../../helpers/onMediaLoad';\nimport themeController from '../../helpers/themeController';\nimport toggleClassName from '../../helpers/toggleClassName';\nimport CallInstance from '../../lib/calls/callInstance';\nimport CALL_STATE from '../../lib/calls/callState';\nimport I18n, {i18n} from '../../lib/langPack';\nimport wrapEmojiText from '../../lib/richTextProcessor/wrapEmojiText';\nimport animationIntersector from '../animationIntersector';\nimport AvatarElement from '../avatar';\nimport ButtonIcon from '../buttonIcon';\nimport GroupCallMicrophoneIconMini from '../groupCall/microphoneIconMini';\nimport {MovableState} from '../movableElement';\nimport PeerTitle from '../peerTitle';\nimport PopupElement from '../popups';\nimport SetTransition from '../singleTransition';\nimport makeButton from './button';\nimport CallDescriptionElement from './description';\nimport callVideoCanvasBlur from './videoCanvasBlur';\n\nconst className = 'call';\n\nconst MIN_WIDTH = 400;\nconst MIN_HEIGHT = 580;\n\nconst INIT_STATE: MovableState = {\n width: MIN_WIDTH,\n height: MIN_HEIGHT\n};\n\nlet previousState: MovableState = {...INIT_STATE};\n\nexport default class PopupCall extends PopupElement {\n private peerId: PeerId;\n\n private description: CallDescriptionElement;\n private emojisSubtitle: HTMLElement;\n\n private partyStates: HTMLElement;\n private partyMutedState: HTMLElement;\n\n private firstButtonsRow: HTMLElement;\n private secondButtonsRow: HTMLElement;\n\n private declineI18nElement: I18n.IntlElement;\n\n private makeButton: (options: Parameters<typeof makeButton>[2]) => HTMLElement;\n private btnAccept: HTMLElement;\n private btnDecline: HTMLElement;\n private btnVideo: HTMLElement;\n private btnScreen: HTMLElement;\n private btnMute: HTMLElement;\n private btnFullScreen: HTMLButtonElement;\n private btnExitFullScreen: HTMLButtonElement;\n\n private movablePanel: MovablePanel;\n private microphoneIcon: GroupCallMicrophoneIconMini;\n private muteI18nElement: I18n.IntlElement;\n\n private videoContainers: {\n input?: HTMLElement,\n output?: HTMLElement\n };\n\n private controlsHover: ControlsHover;\n\n constructor(private instance: CallInstance) {\n super('popup-call', {\n withoutOverlay: true,\n closable: true\n });\n\n this.videoContainers = {};\n\n const {container, listenerSetter} = this;\n container.classList.add(className, 'night');\n\n const avatarContainer = document.createElement('div');\n avatarContainer.classList.add(className + '-avatar');\n\n const peerId = this.peerId = this.instance.interlocutorUserId.toPeerId();\n const avatar = new AvatarElement();\n avatar.classList.add('avatar-full');\n avatar.updateWithOptions({\n isBig: true,\n peerId: peerId\n });\n avatarContainer.append(avatar);\n\n const title = new PeerTitle({\n peerId\n }).element;\n\n title.classList.add(className + '-title');\n\n const subtitle = document.createElement('div');\n subtitle.classList.add(className + '-subtitle');\n\n const description = this.description = new CallDescriptionElement(subtitle);\n\n const emojisSubtitle = this.emojisSubtitle = document.createElement('div');\n emojisSubtitle.classList.add(className + '-emojis');\n\n container.append(avatarContainer, title, subtitle);\n\n if(!IS_MOBILE) {\n this.btnFullScreen = ButtonIcon('fullscreen');\n this.btnExitFullScreen = ButtonIcon('smallscreen hide');\n attachClickEvent(this.btnFullScreen, this.onFullScreenClick, {listenerSetter});\n attachClickEvent(this.btnExitFullScreen, () => cancelFullScreen(), {listenerSetter});\n addFullScreenListener(this.container, this.onFullScreenChange, listenerSetter);\n this.header.prepend(this.btnExitFullScreen);\n this.header.append(this.btnFullScreen);\n\n container.append(emojisSubtitle);\n } else {\n this.header.append(emojisSubtitle);\n }\n\n this.partyStates = document.createElement('div');\n this.partyStates.classList.add(className + '-party-states');\n\n this.partyMutedState = document.createElement('div');\n this.partyMutedState.classList.add(className + '-party-state');\n const stateText = i18n('VoipUserMicrophoneIsOff', [new PeerTitle({peerId, onlyFirstName: true, limitSymbols: 18}).element]);\n stateText.classList.add(className + '-party-state-text');\n const mutedIcon = new GroupCallMicrophoneIconMini(false, true);\n mutedIcon.setState(false, false);\n this.partyMutedState.append(\n mutedIcon.container,\n stateText\n );\n\n this.partyStates.append(this.partyMutedState);\n this.container.append(this.partyStates);\n\n this.makeButton = makeButton.bind(null, className, this.listenerSetter);\n this.constructFirstButtons();\n this.constructSecondButtons();\n\n listenerSetter.add(instance)('state', () => {\n this.updateInstance();\n });\n\n listenerSetter.add(instance)('mediaState', () => {\n this.updateInstance();\n });\n\n this.movablePanel = new MovablePanel({\n listenerSetter,\n movableOptions: {\n minWidth: MIN_WIDTH,\n minHeight: MIN_HEIGHT,\n element: this.element,\n verifyTouchTarget: (e) => {\n const target = e.target;\n if(findUpClassName(target, 'call-button') ||\n findUpClassName(target, 'btn-icon') ||\n isFullScreen()) {\n return false;\n }\n\n return true;\n }\n },\n // onResize: () => this.toggleBigLayout(),\n previousState: !this.instance.wasTryingToJoin && !this.instance.isOutgoing ? {...INIT_STATE} : previousState\n });\n\n const movableElement = this.movablePanel.movable;\n if(movableElement) {\n this.listenerSetter.add(movableElement)('resize', () => {\n this.resizeVideoContainers();\n });\n }\n\n const controlsHover = this.controlsHover = new ControlsHover();\n controlsHover.setup({\n element: this.container,\n listenerSetter: this.listenerSetter,\n showOnLeaveToClassName: 'call-buttons'\n });\n controlsHover.showControls(false);\n\n this.addEventListener('close', () => {\n const {movablePanel} = this;\n previousState = movablePanel.state;\n\n this.microphoneIcon.destroy();\n\n movablePanel.destroy();\n });\n\n this.updateInstance();\n }\n\n public getCallInstance() {\n return this.instance;\n }\n\n private constructFirstButtons() {\n const buttons = this.firstButtonsRow = document.createElement('div');\n buttons.classList.add(className + '-buttons', 'is-first');\n\n const toggleDisability = toggleClassName.bind(null, 'btn-disabled');\n\n const btnVideo = this.btnVideo = this.makeButton({\n text: 'Call.Camera',\n icon: 'videocamera_filled',\n callback: () => {\n const toggle = toggleDisability([btnVideo, btnScreen], true);\n this.instance.toggleVideoSharing().finally(toggle);\n }\n });\n\n const btnScreen = this.btnScreen = this.makeButton({\n text: 'Call.Screen',\n icon: 'sharescreen_filled',\n callback: () => {\n const toggle = toggleDisability([btnVideo, btnScreen], true);\n this.instance.toggleScreenSharing().finally(toggle);\n }\n });\n\n if(!IS_SCREEN_SHARING_SUPPORTED) {\n btnScreen.classList.add('hide');\n this.container.classList.add('no-screen');\n }\n\n this.muteI18nElement = new I18n.IntlElement({\n key: 'Call.Mute'\n });\n const btnMute = this.btnMute = this.makeButton({\n text: this.muteI18nElement.element,\n callback: () => {\n this.instance.toggleMuted();\n }\n });\n\n const microphoneIcon = this.microphoneIcon = new GroupCallMicrophoneIconMini(true, true);\n btnMute.firstElementChild.append(microphoneIcon.container);\n\n // btnVideo.classList.add('disabled');\n // btnScreen.classList.add('disabled');\n\n buttons.append(btnVideo, btnScreen, btnMute);\n this.container.append(buttons);\n }\n\n private constructSecondButtons() {\n const buttons = this.secondButtonsRow = document.createElement('div');\n buttons.classList.add(className + '-buttons', 'is-second');\n\n this.declineI18nElement = new I18n.IntlElement({\n key: 'Call.Decline'\n });\n const btnDecline = this.btnDecline = this.makeButton({\n text: this.declineI18nElement.element,\n icon: 'endcall_filled',\n callback: () => {\n this.instance.hangUp('phoneCallDiscardReasonHangup');\n },\n isDanger: true\n });\n\n const btnAccept = this.btnAccept = this.makeButton({\n text: 'Call.Accept',\n icon: 'phone_filled',\n callback: () => {\n this.instance.acceptCall();\n },\n isConfirm: true\n });\n\n buttons.append(btnDecline, btnAccept);\n this.container.append(buttons);\n }\n\n private onFullScreenClick = () => {\n requestFullScreen(this.container);\n };\n\n private onFullScreenChange = () => {\n const isFull = isFullScreen();\n\n const {btnFullScreen, btnExitFullScreen} = this;\n\n const wasFullScreen = this.container.classList.contains('is-full-screen');\n this.container.classList.toggle('is-full-screen', isFull);\n btnFullScreen && btnFullScreen.classList.toggle('hide', isFull);\n btnExitFullScreen && btnExitFullScreen.classList.toggle('hide', !isFull);\n this.btnClose.classList.toggle('hide', isFull);\n\n if(isFull !== wasFullScreen) {\n animationIntersector.checkAnimations(isFull);\n\n themeController.setThemeColor(isFull ? '#000000' : undefined);\n\n this.resizeVideoContainers();\n }\n };\n\n private createVideoContainer(video: HTMLVideoElement) {\n const _className = className + '-video';\n const container = document.createElement('div');\n container.classList.add(_className + '-container');\n\n video.classList.add(_className);\n if(video.paused) {\n video.play();\n }\n\n attachClickEvent(container, () => {\n if(!container.classList.contains('small')) {\n return;\n }\n\n const big = Object.values(this.videoContainers).find((container) => !container.classList.contains('small'));\n big.classList.add('small');\n big.style.cssText = container.style.cssText;\n container.classList.remove('small');\n container.style.cssText = '';\n\n this.resizeVideoContainers();\n });\n\n const canvas = callVideoCanvasBlur(video);\n canvas.classList.add(_className + '-blur');\n\n container.append(canvas, video);\n\n return container;\n }\n\n private updateInstance() {\n const {instance} = this;\n const {connectionState} = instance;\n if(connectionState === CALL_STATE.CLOSED) {\n if(this.container.classList.contains('is-full-screen')) {\n cancelFullScreen();\n }\n\n this.btnVideo.classList.add('disabled');\n\n this.hide();\n return;\n }\n\n const isPendingIncoming = !instance.isOutgoing && connectionState === CALL_STATE.PENDING;\n this.declineI18nElement.compareAndUpdate({\n key: connectionState === CALL_STATE.PENDING ? 'Call.Decline' : 'Call.End'\n });\n this.btnAccept.classList.toggle('disable', !isPendingIncoming);\n this.btnAccept.classList.toggle('hide-me', !isPendingIncoming);\n this.container.classList.toggle('two-button-rows', isPendingIncoming);\n\n const isMuted = instance.isMuted;\n const onFrame = () => {\n this.btnMute.firstElementChild.classList.toggle('active', isMuted);\n };\n\n const player = this.microphoneIcon.getItem().player;\n this.microphoneIcon.setState(!isMuted, !isMuted, onFrame);\n if(!player) {\n onFrame();\n }\n\n this.muteI18nElement.compareAndUpdate({\n key: isMuted ? 'VoipUnmute' : 'Call.Mute'\n });\n\n const isSharingVideo = instance.isSharingVideo;\n this.btnVideo.firstElementChild.classList.toggle('active', isSharingVideo);\n\n const isSharingScreen = instance.isSharingScreen;\n this.btnScreen.firstElementChild.classList.toggle('active', isSharingScreen);\n\n const outputState = instance.getMediaState('output');\n\n SetTransition({\n element: this.partyMutedState,\n className: 'is-visible',\n forwards: !!outputState?.muted,\n duration: 300\n });\n\n const containers = this.videoContainers;\n const oldContainers = {...containers};\n ['input' as const, 'output' as const].forEach((type) => {\n const mediaState = instance.getMediaState(type);\n const video = instance.getVideoElement(type) as HTMLVideoElement;\n\n const hasFrame = !!(video && video.videoWidth && video.videoHeight);\n if(video && !hasFrame && !video.dataset.hasPromise) {\n video.dataset.hasPromise = '1';\n // container.classList.add('hide');\n onMediaLoad(video).then(() => {\n delete video.dataset.hasPromise;\n this.updateInstance();\n // this.resizeVideoContainers();\n // container.classList.remove('hide');\n });\n }\n\n const isActive = !!video && hasFrame && !!(mediaState && (mediaState.videoState === 'active' || mediaState.screencastState === 'active'));\n let videoContainer = containers[type];\n\n if(isActive && video && !videoContainer) {\n videoContainer = containers[type] = this.createVideoContainer(video);\n this.container.append(videoContainer);\n }\n\n if(!isActive && videoContainer) {\n videoContainer.remove();\n delete containers[type];\n }\n });\n\n {\n const input = containers.input;\n const output = containers.output;\n if(Object.keys(oldContainers).length !== Object.keys(containers).length && input) {\n input.classList.toggle('small', !!output);\n }\n\n if(output && !input) {\n output.classList.remove('small');\n }\n }\n\n this.resizeVideoContainers();\n\n this.container.classList.toggle('no-video', !Object.keys(containers).length);\n\n if(!this.emojisSubtitle.textContent && connectionState < CALL_STATE.EXCHANGING_KEYS) {\n Promise.resolve(instance.getEmojisFingerprint()).then((emojis) => {\n replaceContent(this.emojisSubtitle, wrapEmojiText(emojis.join('')));\n });\n }\n\n this.setDescription();\n }\n\n private resizeVideoContainers() {\n Object.values(this.videoContainers).forEach((container) => {\n const isSmall = container.classList.contains('small');\n if(isSmall) {\n const video = container.querySelector('video');\n const popupWidth = this.movablePanel.state;\n const MAX_WIDTH_PX = 240;\n const MAX_HEIGHT_PX = 240;\n\n const isVertical = video.videoHeight > video.videoWidth;\n const MAX_SIZE = isVertical ? MAX_HEIGHT_PX : MAX_WIDTH_PX;\n\n const biggestSideSize = 1 / 3 * (isFullScreen() ? 0xFFFF : (isVertical ? popupWidth.height : popupWidth.width));\n const widthRatio = isVertical ? video.videoWidth / video.videoHeight : 1;\n const heightRatio = isVertical ? 1 : video.videoHeight / video.videoWidth;\n container.style.width = biggestSideSize * widthRatio + 'px';\n container.style.height = biggestSideSize * heightRatio + 'px';\n container.style.maxWidth = MAX_SIZE * widthRatio + 'px';\n container.style.maxHeight = MAX_SIZE * heightRatio + 'px';\n } else {\n container.style.cssText = '';\n }\n });\n }\n\n private setDescription() {\n this.description.update(this.instance);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport cancelEvent from '../helpers/dom/cancelEvent';\nimport {attachClickEvent} from '../helpers/dom/clickEvent';\nimport ListenerSetter from '../helpers/listenerSetter';\nimport GROUP_CALL_STATE from '../lib/calls/groupCallState';\nimport rootScope from '../lib/rootScope';\nimport ButtonIcon from './buttonIcon';\nimport TopbarWeave from './topbarWeave';\nimport SetTransition from './singleTransition';\nimport PopupGroupCall from './groupCall';\nimport GroupCallDescriptionElement from './groupCall/description';\nimport GroupCallTitleElement from './groupCall/title';\nimport PopupElement from './popups';\nimport throttle from '../helpers/schedulers/throttle';\nimport GroupCallInstance from '../lib/calls/groupCallInstance';\nimport CALL_STATE from '../lib/calls/callState';\nimport replaceContent from '../helpers/dom/replaceContent';\nimport PeerTitle from './peerTitle';\nimport CallDescriptionElement from './call/description';\nimport PopupCall from './call';\nimport GroupCallMicrophoneIconMini from './groupCall/microphoneIconMini';\nimport CallInstance from '../lib/calls/callInstance';\nimport {AppManagers} from '../lib/appManagers/managers';\nimport groupCallsController from '../lib/calls/groupCallsController';\nimport StreamManager from '../lib/calls/streamManager';\nimport callsController from '../lib/calls/callsController';\n\nfunction convertCallStateToGroupState(state: CALL_STATE, isMuted: boolean) {\n switch(state) {\n case CALL_STATE.CLOSING:\n case CALL_STATE.CLOSED:\n return GROUP_CALL_STATE.CLOSED;\n case CALL_STATE.CONNECTED:\n return isMuted ? GROUP_CALL_STATE.MUTED : GROUP_CALL_STATE.UNMUTED;\n default:\n return GROUP_CALL_STATE.CONNECTING;\n }\n}\n\nconst CLASS_NAME = 'topbar-call';\n\nexport default class TopbarCall {\n public container: HTMLElement;\n private listenerSetter: ListenerSetter;\n private weave: TopbarWeave;\n private center: HTMLDivElement;\n private groupCallTitle: GroupCallTitleElement;\n private groupCallDescription: GroupCallDescriptionElement;\n private groupCallMicrophoneIconMini: GroupCallMicrophoneIconMini;\n private callDescription: CallDescriptionElement;\n\n private currentDescription: GroupCallDescriptionElement | CallDescriptionElement;\n\n private instance: GroupCallInstance | any/* CallInstance */;\n private instanceListenerSetter: ListenerSetter;\n\n constructor(\n private managers: AppManagers\n ) {\n const listenerSetter = this.listenerSetter = new ListenerSetter();\n\n listenerSetter.add(callsController)('instance', ({instance}) => {\n if(!this.instance) {\n this.updateInstance(instance);\n }\n });\n\n listenerSetter.add(callsController)('accepting', (instance) => {\n if(this.instance !== instance) {\n this.updateInstance(instance);\n }\n });\n\n listenerSetter.add(groupCallsController)('instance', (instance) => {\n this.updateInstance(instance);\n });\n\n listenerSetter.add(rootScope)('group_call_update', (groupCall) => {\n const instance = groupCallsController.groupCall;\n if(instance?.id === groupCall.id) {\n this.updateInstance(instance);\n }\n });\n\n listenerSetter.add(StreamManager.ANALYSER_LISTENER)('amplitude', ({amplitudes, type}) => {\n const {weave} = this;\n if(!amplitudes.length || !weave/* || type !== 'input' */) return;\n\n let max = 0;\n for(let i = 0; i < amplitudes.length; ++i) {\n const {type, value} = amplitudes[i];\n max = value > max ? value : max;\n }\n\n weave.setAmplitude(max);\n });\n }\n\n private onState = () => {\n this.updateInstance(this.instance);\n };\n\n private clearCurrentInstance() {\n if(!this.instance) return;\n this.center.textContent = '';\n\n if(this.currentDescription) {\n this.currentDescription.detach();\n this.currentDescription = undefined;\n }\n\n this.instance = undefined;\n this.instanceListenerSetter.removeAll();\n }\n\n private updateInstance(instance: TopbarCall['instance']) {\n if(this.construct) {\n this.construct();\n this.construct = undefined;\n }\n\n const isChangingInstance = this.instance !== instance;\n if(isChangingInstance) {\n this.clearCurrentInstance();\n\n this.instance = instance;\n this.instanceListenerSetter = new ListenerSetter();\n\n this.instanceListenerSetter.add(instance as GroupCallInstance)('state', this.onState);\n\n if(instance instanceof GroupCallInstance) {\n this.currentDescription = this.groupCallDescription;\n } else {\n this.currentDescription = this.callDescription;\n this.instanceListenerSetter.add(instance)('muted', this.onState);\n }\n\n this.container.classList.toggle('is-call', !(instance instanceof GroupCallInstance));\n }\n\n const isMuted = this.instance.isMuted;\n const state = instance instanceof GroupCallInstance ? instance.state : convertCallStateToGroupState(instance.connectionState, isMuted);\n\n const {weave} = this;\n\n weave.componentDidMount();\n\n const isClosed = state === GROUP_CALL_STATE.CLOSED;\n if((!document.body.classList.contains('is-calling') || isChangingInstance) || isClosed) {\n if(isClosed) {\n weave.setAmplitude(0);\n }\n\n SetTransition({\n element: document.body,\n className: 'is-calling',\n forwards: !isClosed,\n duration: 250,\n onTransitionEnd: isClosed ? () => {\n weave.componentWillUnmount();\n\n this.clearCurrentInstance();\n } : undefined\n });\n }\n\n if(isClosed) {\n return;\n }\n\n weave.setCurrentState(state, true);\n // if(state === GROUP_CALL_STATE.CONNECTING) {\n // weave.setCurrentState(state, true);\n // } else {\n // /* var a = 0;\n // animate(() => {\n // a += 0.1;\n // if(a > 1) a = 0;\n // weave.setAmplitude(a);\n // return true;\n // });\n // weave.setAmplitude(1); */\n // weave.setCurrentState(state, true);\n // }\n\n this.setTitle(instance);\n this.setDescription(instance);\n this.groupCallMicrophoneIconMini.setState(!isMuted);\n }\n\n private setDescription(instance: TopbarCall['instance']) {\n return this.currentDescription.update(instance as any);\n }\n\n private setTitle(instance: TopbarCall['instance']) {\n if(instance instanceof GroupCallInstance) {\n return this.groupCallTitle.update(instance);\n } else {\n replaceContent(this.center, new PeerTitle({peerId: instance.interlocutorUserId.toPeerId()}).element);\n }\n }\n\n private construct() {\n const {listenerSetter} = this;\n const container = this.container = document.createElement('div');\n container.classList.add('sidebar-header', CLASS_NAME + '-container');\n\n const left = document.createElement('div');\n left.classList.add(CLASS_NAME + '-left');\n\n const groupCallMicrophoneIconMini = this.groupCallMicrophoneIconMini = new GroupCallMicrophoneIconMini();\n\n const mute = ButtonIcon();\n mute.append(groupCallMicrophoneIconMini.container);\n left.append(mute);\n\n const throttledMuteClick = throttle(() => {\n this.instance.toggleMuted();\n }, 600, true);\n\n attachClickEvent(mute, (e) => {\n cancelEvent(e);\n throttledMuteClick();\n }, {listenerSetter});\n\n const center = this.center = document.createElement('div');\n center.classList.add(CLASS_NAME + '-center');\n\n this.groupCallTitle = new GroupCallTitleElement(center);\n this.groupCallDescription = new GroupCallDescriptionElement(left);\n\n this.callDescription = new CallDescriptionElement(left);\n\n const right = document.createElement('div');\n right.classList.add(CLASS_NAME + '-right');\n\n const end = ButtonIcon('endcall_filled');\n right.append(end);\n\n attachClickEvent(end, (e) => {\n cancelEvent(e);\n\n const {instance} = this;\n if(!instance) {\n return;\n }\n\n if(instance instanceof GroupCallInstance) {\n instance.hangUp();\n } else {\n instance.hangUp('phoneCallDiscardReasonHangup');\n }\n }, {listenerSetter});\n\n attachClickEvent(container, () => {\n if(this.instance instanceof GroupCallInstance) {\n if(PopupElement.getPopups(PopupGroupCall).length) {\n return;\n }\n\n PopupElement.createPopup(PopupGroupCall).show();\n } else if(this.instance instanceof CallInstance) {\n const popups = PopupElement.getPopups(PopupCall);\n if(popups.find((popup) => popup.getCallInstance() === this.instance)) {\n return;\n }\n\n PopupElement.createPopup(PopupCall, this.instance).show();\n }\n }, {listenerSetter});\n\n container.append(left, center, right);\n\n const weave = this.weave = new TopbarWeave();\n const weaveContainer = weave.render(CLASS_NAME + '-weave');\n container.prepend(weaveContainer);\n\n document.getElementById('column-center').prepend(container);\n weave.componentDidMount();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {PushNotificationObject} from '../serviceWorker/push';\nimport getPeerTitle from '../../components/wrappers/getPeerTitle';\nimport wrapMessageForReply from '../../components/wrappers/messageForReply';\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport {FontFamily} from '../../config/font';\nimport {NOTIFICATION_BADGE_PATH, NOTIFICATION_ICON_PATH} from '../../config/notifications';\nimport {IS_MOBILE} from '../../environment/userAgent';\nimport IS_VIBRATE_SUPPORTED from '../../environment/vibrateSupport';\nimport deferredPromise, {CancellablePromise} from '../../helpers/cancellablePromise';\nimport drawCircle from '../../helpers/canvas/drawCircle';\nimport customProperties from '../../helpers/dom/customProperties';\nimport idleController from '../../helpers/idleController';\nimport deepEqual from '../../helpers/object/deepEqual';\nimport tsNow from '../../helpers/tsNow';\nimport {Message, MessagePeerReaction, PeerNotifySettings} from '../../layer';\nimport I18n, {FormatterArguments, LangPackKey} from '../langPack';\nimport apiManagerProxy from '../mtproto/mtprotoworker';\nimport singleInstance from '../mtproto/singleInstance';\nimport webPushApiManager, {PushSubscriptionNotify} from '../mtproto/webPushApiManager';\nimport fixEmoji from '../richTextProcessor/fixEmoji';\nimport getAbbreviation from '../richTextProcessor/getAbbreviation';\nimport wrapPlainText from '../richTextProcessor/wrapPlainText';\nimport rootScope from '../rootScope';\nimport appImManager from './appImManager';\nimport appRuntimeManager from './appRuntimeManager';\nimport {AppManagers} from './managers';\nimport generateMessageId from './utils/messageId/generateMessageId';\nimport getMessageThreadId from './utils/messages/getMessageThreadId';\nimport getPeerColorById from './utils/peers/getPeerColorById';\nimport getPeerId from './utils/peers/getPeerId';\nimport {logger} from '../logger';\n\ntype MyNotification = Notification & {\n hidden?: boolean,\n show?: () => void,\n};\n\nexport type NotifyOptions = Partial<{\n tag: string;\n image: string;\n key: string;\n title: string;\n message: string;\n silent: boolean;\n onclick: () => void;\n noIncrement: boolean;\n}>;\n\nexport type NotificationSettings = {\n nodesktop: boolean,\n volume: number,\n novibrate: boolean,\n nopreview: boolean,\n nopush: boolean,\n nosound: boolean\n};\n\nexport class UiNotificationsManager {\n private notificationsUiSupport: boolean;\n private notificationsShown: {[key: string]: MyNotification | true} = {};\n private notificationIndex = 0;\n private notificationsCount = 0;\n private soundsPlayed: {[tag: string]: number} = {};\n private vibrateSupport = IS_VIBRATE_SUPPORTED;\n private nextSoundAt: number;\n private prevSoundVolume: number;\n\n private faviconElements = Array.from(document.head.querySelectorAll<HTMLLinkElement>('link[rel=\"icon\"], link[rel=\"alternate icon\"]'));\n\n private titleBackup = document.title;\n private titleChanged = false;\n private titleInterval: number;\n private prevFavicon: string;\n\n private notifySoundEl: HTMLElement;\n\n private stopped = false;\n\n private topMessagesDeferred: CancellablePromise<void>;\n\n private settings: NotificationSettings = {} as any;\n\n private registeredDevice: any;\n private pushInited = false;\n\n private managers: AppManagers;\n private setAppBadge: (contents?: any) => Promise<void>;\n\n private avatarCanvas: HTMLCanvasElement;\n private avatarContext: CanvasRenderingContext2D;\n private avatarGradients: {[color: string]: CanvasGradient};\n\n private log: ReturnType<typeof logger>;\n\n construct(managers: AppManagers) {\n this.managers = managers;\n\n this.log = logger('NOTIFICATIONS');\n\n navigator.vibrate = navigator.vibrate || (navigator as any).mozVibrate || (navigator as any).webkitVibrate;\n this.setAppBadge = (navigator as any).setAppBadge && (navigator as any).setAppBadge.bind(navigator);\n this.setAppBadge && this.setAppBadge(0);\n\n this.notificationsUiSupport = ('Notification' in window) || ('mozNotification' in navigator);\n\n this.notifySoundEl = document.createElement('div');\n this.notifySoundEl.id = 'notify-sound';\n document.body.append(this.notifySoundEl);\n\n this.topMessagesDeferred = deferredPromise<void>();\n\n singleInstance.addEventListener('deactivated', () => {\n this.stop();\n });\n\n singleInstance.addEventListener('activated', () => {\n if(this.stopped) {\n this.start();\n }\n });\n\n idleController.addEventListener('change', (idle) => {\n if(this.stopped) {\n return;\n }\n\n if(!idle) {\n this.clear();\n }\n\n this.toggleToggler();\n });\n\n rootScope.addEventListener('notification_reset', (peerString) => {\n this.soundReset(peerString);\n });\n\n rootScope.addEventListener('notification_cancel', (str) => {\n this.cancel(str);\n });\n\n if(this.setAppBadge) {\n rootScope.addEventListener('folder_unread', (folder) => {\n if(folder.id === 0) {\n this.setAppBadge(folder.unreadUnmutedPeerIds.size);\n }\n });\n }\n\n webPushApiManager.addEventListener('push_init', (tokenData) => {\n this.pushInited = true;\n if(!this.settings.nodesktop && !this.settings.nopush) {\n if(tokenData) {\n this.registerDevice(tokenData);\n } else {\n webPushApiManager.subscribe();\n }\n } else {\n this.unregisterDevice(tokenData);\n }\n });\n webPushApiManager.addEventListener('push_subscribe', (tokenData) => {\n this.registerDevice(tokenData);\n });\n webPushApiManager.addEventListener('push_unsubscribe', (tokenData) => {\n this.unregisterDevice(tokenData);\n });\n\n rootScope.addEventListener('dialogs_multiupdate', () => {\n // unregisterTopMsgs()\n this.topMessagesDeferred.resolve();\n }, {once: true});\n\n webPushApiManager.addEventListener('push_notification_click', (notificationData) => {\n if(notificationData.action === 'push_settings') {\n /* this.topMessagesDeferred.then(() => {\n $modal.open({\n templateUrl: templateUrl('settings_modal'),\n controller: 'SettingsModalController',\n windowClass: 'settings_modal_window mobile_modal',\n backdrop: 'single'\n })\n }); */\n return;\n }\n\n if(notificationData.action === 'mute1d') {\n this.managers.apiManager.invokeApi('account.updateDeviceLocked', {\n period: 86400\n }).then(() => {\n // var toastData = toaster.pop({\n // type: 'info',\n // body: _('push_action_mute1d_success'),\n // bodyOutputType: 'trustedHtml',\n // clickHandler: () => {\n // toaster.clear(toastData)\n // },\n // showCloseButton: false\n // })\n });\n\n return;\n }\n\n const peerId = notificationData.custom && notificationData.custom.peerId.toPeerId();\n console.log('click', notificationData, peerId);\n if(peerId) {\n this.topMessagesDeferred.then(async() => {\n const chatId = peerId.isAnyChat() ? peerId.toChatId() : undefined;\n if(chatId && !(await this.managers.appChatsManager.hasChat(chatId))) {\n return;\n }\n\n if(peerId.isUser() && !(await this.managers.appUsersManager.hasUser(peerId.toUserId()))) {\n return;\n }\n\n appImManager.setInnerPeer({\n peerId,\n lastMsgId: generateMessageId(+notificationData.custom.msg_id)\n });\n });\n }\n });\n }\n\n public async buildNotification({\n message,\n fwdCount,\n peerReaction,\n peerTypeNotifySettings\n }: {\n message: Message.message | Message.messageService,\n fwdCount?: number,\n peerReaction?: MessagePeerReaction,\n peerTypeNotifySettings?: PeerNotifySettings\n }) {\n const peerId = message.peerId;\n const isAnyChat = peerId.isAnyChat();\n const notification: NotifyOptions = {};\n const [peerString, isForum = false] = await Promise.all([\n this.managers.appPeersManager.getPeerString(peerId),\n isAnyChat && this.managers.appPeersManager.isForum(peerId)\n ]);\n let notificationMessage: string;\n let wrappedMessage = false;\n\n if(peerTypeNotifySettings.show_previews) {\n if(message._ === 'message' && message.fwd_from && fwdCount > 1) {\n notificationMessage = I18n.format('Notifications.Forwarded', true, [fwdCount]);\n } else {\n notificationMessage = await wrapMessageForReply({message, plain: true});\n\n const reaction = peerReaction?.reaction;\n if(reaction?._ === 'reactionEmoji') {\n const langPackKey: LangPackKey = /* isAnyChat ? 'Notification.Group.Reacted' : */'Notification.Contact.Reacted';\n const args: FormatterArguments = [\n fixEmoji(reaction.emoticon), // can be plain heart\n notificationMessage\n ];\n\n /* if(isAnyChat) {\n args.unshift(appPeersManager.getPeerTitle(message.fromId, true));\n } */\n\n notificationMessage = I18n.format(langPackKey, true, args);\n } else {\n wrappedMessage = true;\n }\n }\n } else {\n notificationMessage = I18n.format('Notifications.New', true);\n }\n\n if(peerReaction) {\n notification.noIncrement = true;\n notification.silent = true;\n }\n\n const peerTitleOptions/* : Partial<Parameters<typeof getPeerTitle>[0]> */ = {\n plainText: true as const,\n managers: this.managers\n };\n\n const threadId = isForum ? getMessageThreadId(message, isForum) : undefined;\n const notificationFromPeerId = peerReaction ? getPeerId(peerReaction.peer_id) : message.fromId;\n const peerTitle = notification.title = await getPeerTitle({...peerTitleOptions, peerId, threadId: threadId});\n if(isForum) {\n const peerTitle = await getPeerTitle({...peerTitleOptions, peerId});\n notification.title += ` (${peerTitle})`;\n\n if(wrappedMessage && notificationFromPeerId !== message.peerId) {\n notificationMessage = await getPeerTitle({...peerTitleOptions, peerId: notificationFromPeerId}) +\n ': ' + notificationMessage;\n }\n } else if(isAnyChat && notificationFromPeerId !== message.peerId) {\n notification.title = await getPeerTitle({...peerTitleOptions, peerId: notificationFromPeerId}) +\n ' @ ' +\n notification.title;\n }\n\n notification.title = wrapPlainText(notification.title);\n\n notification.onclick = () => {\n appImManager.setInnerPeer({peerId, lastMsgId: message.mid, threadId});\n };\n\n notification.message = notificationMessage;\n notification.key = 'msg' + message.mid;\n notification.tag = peerString;\n notification.silent = true;// message.pFlags.silent || false;\n\n const peerPhoto = await this.managers.appPeersManager.getPeerPhoto(peerId);\n if(peerPhoto) {\n const url = await this.managers.appAvatarsManager.loadAvatar(peerId, peerPhoto, 'photo_small');\n\n if(!peerReaction) { // ! WARNING, message can be already read\n message = await this.managers.appMessagesManager.getMessageByPeer(message.peerId, message.mid);\n if(!message || !message.pFlags.unread) return;\n }\n\n notification.image = url;\n } else {\n let {avatarCanvas, avatarContext} = this;\n if(!this.avatarCanvas) {\n avatarCanvas = this.avatarCanvas = document.createElement('canvas');\n avatarContext = this.avatarContext = avatarCanvas.getContext('2d');\n\n const SIZE = 54;\n const dpr = 1;\n avatarCanvas.dpr = dpr;\n avatarCanvas.width = avatarCanvas.height = SIZE * dpr;\n\n this.avatarGradients = {};\n } else {\n avatarContext.clearRect(0, 0, avatarCanvas.width, avatarCanvas.height);\n }\n\n const color = getPeerColorById(peerId, true);\n let gradient = this.avatarGradients[color];\n if(!gradient) {\n gradient = this.avatarGradients[color] = avatarContext.createLinearGradient(avatarCanvas.width / 2, 0, avatarCanvas.width / 2, avatarCanvas.height);\n\n const colorTop = customProperties.getProperty(`peer-avatar-${color}-top`);\n const colorBottom = customProperties.getProperty(`peer-avatar-${color}-bottom`);\n gradient.addColorStop(0, colorTop);\n gradient.addColorStop(1, colorBottom);\n }\n\n avatarContext.fillStyle = gradient;\n\n drawCircle(avatarContext, avatarCanvas.width / 2, avatarCanvas.height / 2, avatarCanvas.width / 2);\n avatarContext.fill();\n\n const fontSize = 20 * avatarCanvas.dpr;\n const abbreviation = getAbbreviation(peerTitle);\n\n avatarContext.font = `700 ${fontSize}px ${FontFamily}`;\n avatarContext.textBaseline = 'middle';\n avatarContext.textAlign = 'center';\n avatarContext.fillStyle = 'white';\n avatarContext.fillText(abbreviation.text, avatarCanvas.width / 2, avatarCanvas.height * (window.devicePixelRatio > 1 || true ? .5625 : .5));\n\n notification.image = avatarCanvas.toDataURL();\n }\n\n const pushData: PushNotificationObject = {\n custom: {\n msg_id: '' + message.mid,\n peerId: '' + peerId\n },\n description: '',\n loc_key: '',\n loc_args: [],\n mute: '',\n random_id: 0,\n title: ''\n };\n\n const result = await this.notify(notification, pushData);\n if(result && this.registeredDevice) {\n webPushApiManager.ignorePushByMid(peerId, message.mid);\n }\n }\n\n private toggleToggler(enable = idleController.isIdle) {\n if(IS_MOBILE) return;\n\n const resetTitle = (isBlink?: boolean) => {\n this.titleChanged = false;\n document.title = this.titleBackup;\n this.setFavicon();\n };\n\n window.clearInterval(this.titleInterval);\n this.titleInterval = 0;\n\n if(!enable) {\n resetTitle();\n } else {\n this.titleInterval = window.setInterval(() => {\n const count = this.notificationsCount;\n if(!count) {\n this.toggleToggler(false);\n } else if(this.titleChanged) {\n resetTitle(true);\n } else {\n this.titleChanged = true;\n document.title = I18n.format('Notifications.Count', true, [count]);\n // this.setFavicon('assets/img/favicon_unread.ico');\n\n // fetch('assets/img/favicon.ico')\n // .then((res) => res.blob())\n // .then((blob) => {\n // const img = document.createElement('img');\n // img.src = URL.createObjectURL(blob);\n\n const canvas = document.createElement('canvas');\n canvas.width = 32 * window.devicePixelRatio;\n canvas.height = canvas.width;\n\n const ctx = canvas.getContext('2d');\n ctx.beginPath();\n ctx.arc(canvas.width / 2, canvas.height / 2, canvas.width / 2, 0, 2 * Math.PI, false);\n ctx.fillStyle = '#3390ec';\n ctx.fill();\n\n let fontSize = 24;\n let str = '' + count;\n if(count < 10) {\n fontSize = 22;\n } else if(count < 100) {\n fontSize = 20;\n } else {\n str = '99+';\n fontSize = 16;\n }\n\n fontSize *= window.devicePixelRatio;\n\n ctx.font = `700 ${fontSize}px ${FontFamily}`;\n ctx.textBaseline = 'middle';\n ctx.textAlign = 'center';\n ctx.fillStyle = 'white';\n ctx.fillText(str, canvas.width / 2, canvas.height * .5625);\n\n /* const ctx = canvas.getContext('2d');\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height); */\n\n this.setFavicon(canvas.toDataURL());\n // });\n }\n }, 1000);\n }\n }\n\n private setFavicon(href?: string) {\n if(this.prevFavicon === href) {\n return;\n }\n\n this.prevFavicon = href;\n this.faviconElements.forEach((element, idx, arr) => {\n const link = element.cloneNode() as HTMLLinkElement;\n\n link.dataset.href ||= link.href;\n\n href ??= link.dataset.href;\n link.href = href;\n element.replaceWith(arr[idx] = link);\n });\n }\n\n public async notify(data: NotifyOptions, pushData: PushNotificationObject) {\n this.log('notify', data, idleController.isIdle, this.notificationsUiSupport, this.stopped);\n\n if(this.stopped) {\n return;\n }\n\n data.image ||= NOTIFICATION_ICON_PATH;\n\n if(!data.noIncrement) {\n ++this.notificationsCount;\n }\n\n if(!this.titleInterval) {\n this.toggleToggler();\n }\n\n const idx = ++this.notificationIndex;\n const key = data.key || 'k' + idx;\n this.notificationsShown[key] = true;\n\n const now = tsNow();\n if(this.settings.volume > 0 && !this.settings.nosound/* &&\n (\n !data.tag ||\n !this.soundsPlayed[data.tag] ||\n now > this.soundsPlayed[data.tag] + 60000\n ) */\n ) {\n this.testSound(this.settings.volume);\n this.soundsPlayed[data.tag] = now;\n }\n\n if(!this.notificationsUiSupport ||\n 'Notification' in window && Notification.permission !== 'granted') {\n return;\n }\n\n if(this.settings.nodesktop) {\n if(this.vibrateSupport && !this.settings.novibrate) {\n navigator.vibrate([200, 100, 200]);\n return;\n }\n\n return;\n }\n\n if(!('Notification' in window)) {\n return;\n }\n\n let notification: MyNotification;\n\n const notificationOptions: NotificationOptions = {\n badge: NOTIFICATION_BADGE_PATH,\n icon: data.image || '',\n body: data.message || '',\n tag: data.tag || '',\n silent: data.silent || false,\n data: pushData\n };\n\n try {\n if(data.tag) {\n for(const i in this.notificationsShown) {\n const notification = this.notificationsShown[i];\n if(typeof(notification) !== 'boolean' && notification.tag === data.tag) {\n notification.hidden = true;\n }\n }\n }\n\n // throw new Error('test');\n notification = new Notification(data.title, notificationOptions);\n } catch(e) {\n try {\n const registration = await navigator.serviceWorker.ready;\n await registration.showNotification(data.title, notificationOptions);\n const notifications = await registration.getNotifications({tag: notificationOptions.tag});\n notification = notifications[notifications.length - 1];\n } catch(err) {\n this.log.error('creating push error', err, data, notificationOptions);\n }\n\n if(!notification) {\n this.notificationsUiSupport = false;\n webPushApiManager.setLocalNotificationsDisabled();\n return;\n }\n }\n\n notification.onclick = () => {\n this.log('notification onclick');\n notification.close();\n appRuntimeManager.focus();\n this.clear();\n data.onclick?.();\n };\n\n notification.onclose = () => {\n this.log('notification onclose');\n if(!notification.hidden) {\n delete this.notificationsShown[key];\n this.clear();\n }\n };\n\n notification.show?.();\n this.notificationsShown[key] = notification;\n\n if(!IS_MOBILE) {\n setTimeout(() => {\n this.hide(key);\n }, 8000);\n }\n\n return true;\n }\n\n public updateLocalSettings = () => {\n const keys = ['notify_nodesktop', 'notify_volume', 'notify_novibrate', 'notify_nopreview', 'notify_nopush'];\n const promises = keys.map(() => undefined);\n // const promises = keys.map((k) => stateStorage.get(k as any));\n Promise.all(promises)\n .then((updSettings) => {\n this.settings.nodesktop = updSettings[0];\n this.settings.volume = updSettings[1] === undefined ? 0.5 : updSettings[1];\n this.settings.novibrate = updSettings[2];\n this.settings.nopreview = updSettings[3];\n this.settings.nopush = updSettings[4];\n\n if(this.pushInited) {\n const needPush = !this.settings.nopush && !this.settings.nodesktop && webPushApiManager.isAvailable || false;\n const hasPush = this.registeredDevice !== false;\n if(needPush !== hasPush) {\n if(needPush) {\n webPushApiManager.subscribe();\n } else {\n webPushApiManager.unsubscribe();\n }\n }\n }\n\n webPushApiManager.setSettings(this.settings);\n });\n\n apiManagerProxy.getState().then((state) => {\n this.settings.nosound = !state.settings.notifications.sound;\n });\n }\n\n public getLocalSettings() {\n return this.settings;\n }\n\n private hide(key: string) {\n const notification = this.notificationsShown[key];\n if(notification) {\n this.closeNotification(notification);\n }\n }\n\n public soundReset(tag: string) {\n delete this.soundsPlayed[tag];\n }\n\n private requestPermission = () => {\n Notification.requestPermission();\n window.removeEventListener('click', this.requestPermission);\n };\n\n public testSound(volume: number) {\n const now = tsNow();\n if(this.nextSoundAt && now < this.nextSoundAt && this.prevSoundVolume === volume) {\n return;\n }\n\n this.nextSoundAt = now + 1000;\n this.prevSoundVolume = volume;\n const filename = 'assets/audio/notification.mp3';\n const audio = document.createElement('audio');\n audio.autoplay = true;\n audio.setAttribute('mozaudiochannel', 'notification');\n audio.volume = volume;\n audio.innerHTML = `\n <source src=\"${filename}\" type=\"audio/mpeg\" />\n <embed hidden=\"true\" autostart=\"true\" loop=\"false\" volume=\"${volume * 100}\" src=\"${filename}\" />\n `;\n this.notifySoundEl.append(audio);\n\n audio.addEventListener('ended', () => {\n audio.remove();\n }, {once: true});\n }\n\n public cancel(key: string) {\n const notification = this.notificationsShown[key];\n this.log('cancel', key, notification);\n if(notification) {\n if(this.notificationsCount > 0) {\n --this.notificationsCount;\n }\n\n this.closeNotification(notification);\n delete this.notificationsShown[key];\n }\n }\n\n private closeNotification(notification: boolean | MyNotification) {\n try {\n if(typeof(notification) !== 'boolean' && notification.close) {\n this.log('close notification', notification);\n notification.hidden = true;\n notification.close();\n }\n } catch(e) {}\n }\n\n public clear() {\n this.log.warn('clear');\n\n for(const i in this.notificationsShown) {\n const notification = this.notificationsShown[i];\n this.closeNotification(notification);\n }\n\n this.notificationsShown = {};\n this.notificationsCount = 0;\n\n webPushApiManager.hidePushNotifications();\n }\n\n public start() {\n this.log('start');\n\n this.updateLocalSettings();\n rootScope.addEventListener('settings_updated', this.updateLocalSettings);\n webPushApiManager.start();\n\n if(!this.notificationsUiSupport) {\n return false;\n }\n\n if('Notification' in window && Notification.permission !== 'granted' && Notification.permission !== 'denied') {\n window.addEventListener('click', this.requestPermission);\n }\n\n try {\n if('onbeforeunload' in window) {\n window.addEventListener('beforeunload', this.clear);\n }\n } catch(e) {}\n }\n\n private stop() {\n this.log('stop');\n\n this.clear();\n window.clearInterval(this.titleInterval);\n this.titleInterval = 0;\n this.setFavicon();\n this.stopped = true;\n }\n\n private registerDevice(tokenData: PushSubscriptionNotify) {\n if(this.registeredDevice && deepEqual(this.registeredDevice, tokenData)) {\n return false;\n }\n\n this.managers.apiManager.invokeApi('account.registerDevice', {\n token_type: tokenData.tokenType,\n token: tokenData.tokenValue,\n other_uids: [],\n app_sandbox: false,\n secret: new Uint8Array()\n }).then(() => {\n this.log('registered device');\n this.registeredDevice = tokenData;\n }, (error) => {\n error.handled = true;\n });\n }\n\n private unregisterDevice(tokenData: PushSubscriptionNotify) {\n if(!this.registeredDevice) {\n return false;\n }\n\n this.managers.apiManager.invokeApi('account.unregisterDevice', {\n token_type: tokenData.tokenType,\n token: tokenData.tokenValue,\n other_uids: []\n }).then(() => {\n this.registeredDevice = false;\n }, (error) => {\n error.handled = true;\n });\n }\n}\n\nconst uiNotificationsManager = new UiNotificationsManager();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.uiNotificationsManager = uiNotificationsManager);\nexport default uiNotificationsManager;\n","export const NOTIFICATION_ICON_PATH = 'assets/img/logo_filled_rounded.png';\nexport const NOTIFICATION_BADGE_PATH = 'assets/img/logo_plain.svg'; // masked\n","export default async function getFilesFromEvent(e: ClipboardEvent | DragEvent, onlyTypes = false): Promise<any[]> {\n const files: any[] = [];\n\n const scanFiles = async(entry: any, item: DataTransferItem) => {\n if(entry.isDirectory) {\n const directoryReader = entry.createReader();\n await new Promise<void>((resolve, reject) => {\n directoryReader.readEntries(async(entries: any) => {\n for(const entry of entries) {\n await scanFiles(entry, item);\n }\n\n resolve();\n });\n });\n } else if(entry) {\n if(onlyTypes) {\n files.push(entry.type);\n } else {\n const itemFile = item.getAsFile(); // * Safari can't handle entry.file with pasting\n const file = entry instanceof File ?\n entry :\n (\n entry instanceof DataTransferItem ?\n entry.getAsFile() :\n await new Promise((resolve, reject) => entry.file(resolve, (err: any) => resolve(itemFile)))\n );\n\n /* if(!onlyTypes) {\n console.log('getFilesFromEvent: got file', item, file);\n } */\n\n if(!file) return;\n files.push(file);\n }\n }\n };\n\n if(e instanceof DragEvent && e.dataTransfer.files && !e.dataTransfer.items) {\n for(let i = 0; i < e.dataTransfer.files.length; i++) {\n const file = e.dataTransfer.files[i];\n files.push(onlyTypes ? file.type : file);\n }\n } else {\n // @ts-ignore\n const items = (e.dataTransfer || e.clipboardData || e.originalEvent.clipboardData).items;\n\n const promises: Promise<any>[] = [];\n for(let i = 0; i < items.length; ++i) {\n const item: DataTransferItem = items[i];\n if(item.kind === 'file') {\n const entry = (onlyTypes ? item : item.webkitGetAsEntry()) || item.getAsFile();\n promises.push(scanFiles(entry, item));\n }\n }\n\n await Promise.all(promises);\n }\n\n /* if(!onlyTypes) {\n console.log('getFilesFromEvent: got files:', e, files);\n } */\n\n return files;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {T_ME_PREFIXES} from '../lib/mtproto/mtproto_config';\nimport cancelEvent from './dom/cancelEvent';\nimport parseUriParams from './string/parseUriParams';\n\nexport default function addAnchorListener<Params extends {pathnameParams?: any, uriParams?: any}>(options: {\n name: 'showMaskedAlert' | 'execBotCommand' | 'searchByHashtag' | 'addstickers' | 'im' |\n 'resolve' | 'privatepost' | 'addstickers' | 'voicechat' | 'joinchat' | 'join' | 'invoice' |\n 'addemoji' | 'setMediaTimestamp',\n protocol?: 'tg',\n callback: (params: Params, element?: HTMLAnchorElement) => boolean | any,\n noPathnameParams?: boolean,\n noUriParams?: boolean,\n noCancelEvent?: boolean\n}) {\n (window as any)[(options.protocol ? options.protocol + '_' : '') + options.name] = (element?: HTMLAnchorElement/* , e: Event */) => {\n !options.noCancelEvent && cancelEvent(null);\n\n let href = element.href;\n if(!href) {\n return;\n }\n\n let pathnameParams: any[];\n let uriParams: any;\n\n const u = new URL(href);\n const match = u.host.match(/(.+?)\\.t(?:elegram)?\\.me/);\n if(match && !T_ME_PREFIXES.has(match[1])) {\n u.pathname = match[1] + (u.pathname === '/' ? '' : u.pathname);\n href = u.toString();\n }\n\n if(!options.noPathnameParams) pathnameParams = new URL(href).pathname.split('/').slice(1);\n if(!options.noUriParams) uriParams = parseUriParams(href);\n\n const res = options.callback({pathnameParams, uriParams} as Params, element);\n return res === undefined ? res : false;\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport PopupElement from '.';\nimport {attachClickEvent} from '../../helpers/dom/clickEvent';\nimport paymentsWrapCurrencyAmount from '../../helpers/paymentsWrapCurrencyAmount';\nimport {PremiumGiftOption} from '../../layer';\nimport appImManager from '../../lib/appManagers/appImManager';\nimport I18n, {i18n, _i18n} from '../../lib/langPack';\nimport AvatarElement from '../avatar';\nimport Button from '../button';\nimport CheckboxField from '../checkboxField';\nimport Row from '../row';\nimport wrapPeerTitle from '../wrappers/peerTitle';\n\nconst className = 'popup-gift-premium';\n\nexport default class PopupGiftPremium extends PopupElement {\n constructor(\n private peerId: PeerId,\n private giftOptions: PremiumGiftOption[]\n ) {\n super(className, {closable: true, overlayClosable: true, body: true, scrollable: true});\n\n this.construct();\n }\n\n public async construct() {\n const {peerId, giftOptions} = this;\n const avatar = new AvatarElement();\n avatar.classList.add('avatar-100', className + '-avatar');\n await avatar.updateWithOptions({\n peerId\n });\n\n const title = document.createElement('span');\n _i18n(title, 'GiftTelegramPremiumTitle');\n title.classList.add(className + '-title');\n\n const subtitle = i18n('GiftTelegramPremiumDescription', [await wrapPeerTitle({peerId})]);\n subtitle.classList.add(className + '-subtitle');\n\n const shortestOption = this.giftOptions.slice().sort((a, b) => a.months - b.months)[0];\n\n const wrapCurrency = (amount: number | string) => paymentsWrapCurrencyAmount(amount, shortestOption.currency, false, true);\n\n const rows = this.giftOptions.map((giftOption, idx) => {\n let subtitle = i18n('PricePerMonth', [wrapCurrency(+giftOption.amount / giftOption.months)]);\n if(giftOption !== shortestOption) {\n const span = document.createElement('span');\n const badge = document.createElement('span');\n badge.classList.add(className + '-discount');\n const shortestAmount = +shortestOption.amount * giftOption.months / shortestOption.months;\n const discount = Math.round((1 - +giftOption.amount / shortestAmount) * 100);\n badge.textContent = '-' + discount + '%';\n span.append(badge, subtitle);\n subtitle = span;\n }\n\n const isYears = !(giftOption.months % 12);\n const checkboxField = new CheckboxField({\n // text: 'Months',\n // textArgs: [giftOption.months],\n checked: idx === 0,\n round: true,\n name: 'gift-months',\n asRadio: true\n });\n\n const row = new Row({\n title: i18n(isYears ? 'Years' : 'Months', [isYears ? giftOption.months / 12 : giftOption.months]),\n checkboxField,\n clickable: true,\n subtitle,\n titleRightSecondary: wrapCurrency(giftOption.amount)\n });\n\n row.container.classList.add(className + '-option');\n\n return row;\n });\n\n const form = document.createElement('form');\n form.classList.add(className + '-options');\n form.append(...rows.map((row) => row.container));\n\n const buttonText = new I18n.IntlElement({key: 'GiftSubscriptionFor', args: [wrapCurrency(giftOptions[0].amount)]});\n\n const getSelectedOption = () => giftOptions[rows.findIndex((row) => row.checkboxField.checked)];\n\n this.listenerSetter.add(form)('change', () => {\n buttonText.compareAndUpdate({\n args: [\n wrapCurrency(getSelectedOption().amount)\n ]\n });\n });\n\n const giftButton = Button(`btn-primary ${className}-confirm shimmer`);\n giftButton.append(buttonText.element);\n\n attachClickEvent(giftButton, () => {\n const giftOption = getSelectedOption();\n appImManager.openUrl(giftOption.bot_url);\n this.hide();\n }, {listenerSetter: this.listenerSetter});\n\n this.scrollable.append(\n avatar,\n title,\n subtitle,\n form,\n giftButton\n );\n\n this.show();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {GroupCallId, MyGroupCall} from './appGroupCallsManager';\nimport type GroupCallInstance from '../calls/groupCallInstance';\nimport type CallInstance from '../calls/callInstance';\nimport animationIntersector, {AnimationItemGroup} from '../../components/animationIntersector';\nimport appSidebarLeft, {LEFT_COLUMN_ACTIVE_CLASSNAME} from '../../components/sidebarLeft';\nimport appSidebarRight, {RIGHT_COLUMN_ACTIVE_CLASSNAME} from '../../components/sidebarRight';\nimport mediaSizes, {ScreenSize} from '../../helpers/mediaSizes';\nimport {logger, LogTypes} from '../logger';\nimport rootScope from '../rootScope';\nimport Chat, {ChatType} from '../../components/chat/chat';\nimport PopupNewMedia, {getCurrentNewMediaPopup} from '../../components/popups/newMedia';\nimport MarkupTooltip from '../../components/chat/markupTooltip';\nimport IS_TOUCH_SUPPORTED from '../../environment/touchSupport';\nimport SetTransition from '../../components/singleTransition';\nimport ChatDragAndDrop from '../../components/chat/dragAndDrop';\nimport {doubleRaf} from '../../helpers/schedulers';\nimport lottieLoader from '../rlottie/lottieLoader';\nimport useHeavyAnimationCheck, {dispatchHeavyAnimationEvent} from '../../hooks/useHeavyAnimationCheck';\nimport stateStorage from '../stateStorage';\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport appNavigationController from '../../components/appNavigationController';\nimport AppPrivateSearchTab from '../../components/sidebarRight/tabs/search';\nimport I18n, {i18n, join, LangPackKey} from '../langPack';\nimport {ChatFull, ChatInvite, ChatParticipant, ChatParticipants, Message, MessageAction, MessageMedia, SendMessageAction, User, Chat as MTChat, UrlAuthResult, WallPaper, Config} from '../../layer';\nimport PeerTitle from '../../components/peerTitle';\nimport PopupPeer, {PopupPeerCheckboxOptions} from '../../components/popups/peer';\nimport blurActiveElement from '../../helpers/dom/blurActiveElement';\nimport cancelEvent from '../../helpers/dom/cancelEvent';\nimport disableTransition from '../../helpers/dom/disableTransition';\nimport placeCaretAtEnd from '../../helpers/dom/placeCaretAtEnd';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport whichChild from '../../helpers/dom/whichChild';\nimport PopupElement from '../../components/popups';\nimport singleInstance, {InstanceDeactivateReason, SingleInstance} from '../mtproto/singleInstance';\nimport PopupStickers from '../../components/popups/stickers';\nimport PopupJoinChatInvite from '../../components/popups/joinChatInvite';\nimport {toast, toastNew} from '../../components/toast';\nimport debounce from '../../helpers/schedulers/debounce';\nimport pause from '../../helpers/schedulers/pause';\nimport {InternalLink, InternalLinkTypeMap, INTERNAL_LINK_TYPE} from './internalLink';\nimport MEDIA_MIME_TYPES_SUPPORTED from '../../environment/mediaMimeTypesSupport';\nimport IMAGE_MIME_TYPES_SUPPORTED from '../../environment/imageMimeTypesSupport';\nimport {NULL_PEER_ID} from '../mtproto/mtproto_config';\nimport telegramMeWebManager from '../mtproto/telegramMeWebManager';\nimport {ONE_DAY} from '../../helpers/date';\nimport TopbarCall from '../../components/topbarCall';\nimport confirmationPopup from '../../components/confirmationPopup';\nimport IS_GROUP_CALL_SUPPORTED from '../../environment/groupCallSupport';\nimport IS_CALL_SUPPORTED from '../../environment/callSupport';\nimport {CallType} from '../calls/types';\nimport {Modify, SendMessageEmojiInteractionData} from '../../types';\nimport htmlToSpan from '../../helpers/dom/htmlToSpan';\nimport getVisibleRect from '../../helpers/dom/getVisibleRect';\nimport {simulateClickEvent} from '../../helpers/dom/clickEvent';\nimport PopupCall from '../../components/call';\nimport copy from '../../helpers/object/copy';\nimport getObjectKeysAndSort from '../../helpers/object/getObjectKeysAndSort';\nimport numberThousandSplitter from '../../helpers/number/numberThousandSplitter';\nimport ChatBackgroundPatternRenderer from '../../components/chat/patternRenderer';\nimport {IS_FIREFOX} from '../../environment/userAgent';\nimport compareVersion from '../../helpers/compareVersion';\nimport {AppManagers} from './managers';\nimport uiNotificationsManager from './uiNotificationsManager';\nimport appMediaPlaybackController from '../../components/appMediaPlaybackController';\nimport {PHONE_NUMBER_REG_EXP} from '../richTextProcessor';\nimport wrapEmojiText from '../richTextProcessor/wrapEmojiText';\nimport wrapRichText, {CustomEmojiRendererElement, renderEmojis} from '../richTextProcessor/wrapRichText';\nimport wrapUrl from '../richTextProcessor/wrapUrl';\nimport generateMessageId from './utils/messageId/generateMessageId';\nimport getUserStatusString from '../../components/wrappers/getUserStatusString';\nimport getChatMembersString from '../../components/wrappers/getChatMembersString';\nimport {STATE_INIT} from '../../config/state';\nimport CacheStorageController from '../files/cacheStorage';\nimport themeController from '../../helpers/themeController';\nimport overlayCounter from '../../helpers/overlayCounter';\nimport appDialogsManager from './appDialogsManager';\nimport idleController from '../../helpers/idleController';\nimport EventListenerBase from '../../helpers/eventListenerBase';\nimport {AckedResult} from '../mtproto/superMessagePort';\nimport groupCallsController from '../calls/groupCallsController';\nimport callsController from '../calls/callsController';\nimport getFilesFromEvent from '../../helpers/files/getFilesFromEvent';\nimport apiManagerProxy from '../mtproto/mtprotoworker';\nimport appRuntimeManager from './appRuntimeManager';\nimport paymentsWrapCurrencyAmount from '../../helpers/paymentsWrapCurrencyAmount';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport {CLICK_EVENT_NAME} from '../../helpers/dom/clickEvent';\nimport PopupPayment from '../../components/popups/payment';\nimport wrapPeerTitle from '../../components/wrappers/peerTitle';\nimport NBSP from '../../helpers/string/nbsp';\nimport {makeMediaSize, MediaSize} from '../../helpers/mediaSize';\nimport {MiddleEllipsisElement} from '../../components/middleEllipsis';\nimport addAnchorListener from '../../helpers/addAnchorListener';\nimport parseUriParams from '../../helpers/string/parseUriParams';\nimport getMessageThreadId from './utils/messages/getMessageThreadId';\nimport findUpTag from '../../helpers/dom/findUpTag';\nimport {MTAppConfig} from '../mtproto/appConfig';\nimport PopupForward from '../../components/popups/forward';\nimport AppBackgroundTab from '../../components/sidebarLeft/tabs/background';\nimport partition from '../../helpers/array/partition';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport liteMode, {LiteModeKey} from '../../helpers/liteMode';\nimport RLottiePlayer from '../rlottie/rlottiePlayer';\nimport PopupGiftPremium from '../../components/popups/giftPremium';\nimport assumeType from '../../helpers/assumeType';\nimport noop from '../../helpers/noop';\n\nexport type ChatSavedPosition = {\n mids: number[],\n top: number\n};\n\nexport type ChatSetPeerOptions = {\n peerId: PeerId,\n lastMsgId?: number,\n threadId?: number,\n startParam?: string,\n stack?: number,\n commentId?: number,\n type?: ChatType,\n mediaTimestamp?: number\n};\n\nexport type ChatSetInnerPeerOptions = Modify<ChatSetPeerOptions, {\n peerId: PeerId,\n type?: ChatType\n}>;\n\nexport enum APP_TABS {\n CHATLIST,\n CHAT,\n PROFILE\n}\n\nexport class AppImManager extends EventListenerBase<{\n chat_changing: (details: {from: Chat, to: Chat}) => void,\n peer_changed: (chat: Chat) => void,\n peer_changing: (chat: Chat) => void,\n tab_changing: (tabId: number) => void\n}> {\n public columnEl = document.getElementById('column-center') as HTMLDivElement;\n public chatsContainer: HTMLElement;\n\n public offline = false;\n public updateStatusInterval = 0;\n\n public log: ReturnType<typeof logger>;\n\n public setPeerPromise: Promise<void> = null;\n\n private tabId: APP_TABS;\n\n public chats: Chat[] = [];\n private prevTab: HTMLElement;\n private chatsSelectTabDebounced: () => void;\n\n public markupTooltip: MarkupTooltip;\n private backgroundPromises: {[slug: string]: Promise<string>};\n\n private topbarCall: TopbarCall;\n public emojiAnimationContainer: HTMLDivElement;\n\n private lastBackgroundUrl: string;\n\n public managers: AppManagers;\n\n public cacheStorage = new CacheStorageController('cachedFiles');\n public customEmojiSize: MediaSize;\n\n get myId() {\n return rootScope.myId;\n }\n\n get chat(): Chat {\n return this.chats[this.chats.length - 1];\n }\n\n public construct(managers: AppManagers) {\n this.managers = managers;\n\n const {\n apiUpdatesManager\n } = managers;\n apiUpdatesManager.attach(I18n.lastRequestedLangCode);\n\n appMediaPlaybackController.construct(managers);\n uiNotificationsManager.construct(managers);\n uiNotificationsManager.start();\n\n this.log = logger('IM', LogTypes.Log | LogTypes.Warn | LogTypes.Debug | LogTypes.Error);\n\n this.backgroundPromises = {};\n STATE_INIT.settings.themes.forEach((theme) => {\n const themeSettings = theme.settings;\n if(!themeSettings) {\n return;\n }\n\n const {wallpaper} = themeSettings;\n const slug = (wallpaper as WallPaper.wallPaper).slug;\n if(!slug) {\n return;\n }\n\n const url = 'assets/img/' + slug + '.svg' + (IS_FIREFOX ? '?1' : '');\n this.backgroundPromises[slug] = Promise.resolve(url);\n });\n\n this.selectTab(APP_TABS.CHATLIST);\n\n idleController.addEventListener('change', (idle) => {\n this.offline = idle;\n this.updateStatus();\n if(idle) {\n clearInterval(this.updateStatusInterval);\n } else {\n this.updateStatusInterval = window.setInterval(() => this.updateStatus(), 50e3);\n }\n });\n\n this.chatsContainer = document.createElement('div');\n this.chatsContainer.classList.add('chats-container', 'tabs-container');\n this.chatsContainer.dataset.animation = 'navigation';\n\n this.emojiAnimationContainer = document.createElement('div');\n this.emojiAnimationContainer.classList.add('emoji-animation-container');\n this.appendEmojiAnimationContainer(mediaSizes.activeScreen);\n\n this.columnEl.append(this.chatsContainer);\n\n this.createNewChat();\n this.chatsSelectTab(this.chat.container);\n\n appNavigationController.onHashChange = this.onHashChange;\n // window.addEventListener('hashchange', this.onHashChange);\n\n this.setSettings();\n rootScope.addEventListener('settings_updated', this.setSettings);\n\n const onPremiumToggle = (isPremium: boolean) => {\n document.body.classList.toggle('is-premium', isPremium);\n };\n rootScope.addEventListener('premium_toggle', onPremiumToggle);\n onPremiumToggle(rootScope.premium);\n this.managers.rootScope.getPremium().then(onPremiumToggle);\n\n useHeavyAnimationCheck(() => {\n animationIntersector.setOnlyOnePlayableGroup('lock');\n animationIntersector.checkAnimations2(true);\n }, () => {\n animationIntersector.setOnlyOnePlayableGroup();\n animationIntersector.checkAnimations2(false);\n });\n\n themeController.AppBackgroundTab = AppBackgroundTab;\n\n if(IS_FIREFOX && apiManagerProxy.oldVersion && compareVersion(apiManagerProxy.oldVersion, '1.4.3') === -1) {\n this.deleteFilesIterative((response) => {\n return response.headers.get('Content-Type') === 'image/svg+xml';\n }).then(() => {\n this.applyCurrentTheme();\n });\n } else {\n this.applyCurrentTheme();\n }\n\n // * fix simultaneous opened both sidebars, can happen when floating sidebar is opened with left sidebar\n mediaSizes.addEventListener('changeScreen', (from, to) => {\n if(document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME) &&\n document.body.classList.contains(RIGHT_COLUMN_ACTIVE_CLASSNAME)) {\n appSidebarRight.toggleSidebar(false);\n }\n\n this.appendEmojiAnimationContainer(to);\n });\n\n mediaSizes.addEventListener('resize', () => {\n // const perf = performance.now();\n const rect = this.chatsContainer.getBoundingClientRect();\n ChatBackgroundPatternRenderer.resizeInstances(rect.width, rect.height).then(() => {\n // this.log.warn('resize bg time:', performance.now() - perf);\n // for(const chat of this.chats) {\n // if(chat.renderDarkPattern) {\n // chat.renderDarkPattern();\n // }\n // }\n });\n });\n\n this.addEventListener('peer_changing', (chat) => {\n this.saveChatPosition(chat);\n });\n\n rootScope.addEventListener('theme_change', () => {\n this.applyCurrentTheme();\n });\n\n rootScope.addEventListener('choosing_sticker', (choosing) => {\n this.setChoosingStickerTyping(!choosing);\n });\n\n rootScope.addEventListener('peer_title_edit', ({peerId, threadId}) => {\n if(this.chat?.peerId === peerId && !threadId && this.tabId !== undefined) {\n this.overrideHash(peerId);\n }\n });\n\n rootScope.addEventListener('peer_typings', ({peerId, typings}) => {\n const chat = this.chat;\n if(\n !chat ||\n chat.peerId !== peerId ||\n overlayCounter.isOverlayActive || (\n mediaSizes.activeScreen === ScreenSize.mobile &&\n this.tabId !== APP_TABS.CHAT\n )\n ) {\n return;\n }\n\n const typing = typings.find((typing) => typing.action._ === 'sendMessageEmojiInteraction');\n if(typing?.action?._ === 'sendMessageEmojiInteraction') {\n const action = typing.action;\n const bubble = chat.bubbles.bubbles[generateMessageId(typing.action.msg_id)];\n if(bubble && bubble.classList.contains('emoji-big') && getVisibleRect(bubble, chat.bubbles.scrollable.container)) {\n const stickerWrapper: HTMLElement = bubble.querySelector('.media-sticker-wrapper:not(.bubble-hover-reaction-sticker):not(.reaction-sticker)');\n\n const data: SendMessageEmojiInteractionData = JSON.parse(action.interaction.data);\n data.a.forEach((a) => {\n setTimeout(() => {\n simulateClickEvent(stickerWrapper);\n }, a.t * 1000);\n });\n\n this.managers.appMessagesManager.setTyping(peerId, {\n _: 'sendMessageEmojiInteractionSeen',\n emoticon: action.emoticon\n });\n }\n }\n });\n\n const onInstanceDeactivated = (reason: InstanceDeactivateReason) => {\n const isUpdated = reason === 'version';\n const popup = PopupElement.createPopup(PopupElement, 'popup-instance-deactivated', {overlayClosable: true});\n const c = document.createElement('div');\n c.classList.add('instance-deactivated-container');\n (popup as any).container.replaceWith(c);\n\n const header = document.createElement('div');\n header.classList.add('header');\n header.append(i18n(isUpdated ? 'Deactivated.Version.Title' : 'Deactivated.Title'));\n\n const subtitle = document.createElement('div');\n subtitle.classList.add('subtitle');\n subtitle.append(i18n(isUpdated ? 'Deactivated.Version.Subtitle' : 'Deactivated.Subtitle'));\n\n c.append(header, subtitle);\n\n document.body.classList.add('deactivated');\n\n const onClose = isUpdated ? () => {\n appRuntimeManager.reload();\n } : () => {\n document.body.classList.add('deactivated-backwards');\n\n singleInstance.activateInstance();\n\n setTimeout(() => {\n document.body.classList.remove('deactivated', 'deactivated-backwards');\n }, 333);\n };\n\n popup.addEventListener('close', onClose);\n popup.show();\n };\n\n singleInstance.addEventListener('deactivated', onInstanceDeactivated);\n if(singleInstance.deactivatedReason) {\n onInstanceDeactivated(singleInstance.deactivatedReason);\n }\n\n // remove scroll listener when setting chat to tray\n this.addEventListener('chat_changing', ({to}) => {\n this.toggleChatGradientAnimation(to);\n });\n\n rootScope.addEventListener('service_notification', (update) => {\n confirmationPopup({\n button: {langKey: 'OK', isCancel: true},\n description: wrapRichText(update.message)\n });\n });\n\n rootScope.addEventListener('payment_sent', async({peerId, mid, receiptMessage}) => {\n const message = await this.managers.appMessagesManager.getMessageByPeer(peerId, mid);\n if(!message) {\n return;\n }\n\n const action = receiptMessage.action as MessageAction.messageActionPaymentSent;\n toastNew({\n langPackKey: 'PaymentInfoHint',\n langPackArguments: [\n paymentsWrapCurrencyAmount(action.total_amount, action.currency),\n wrapEmojiText(((message as Message.message).media as MessageMedia.messageMediaInvoice).title)\n ]\n });\n });\n\n (window as any).onSpoilerClick = (e: MouseEvent) => {\n const spoiler = findUpClassName(e.target, 'spoiler');\n const parentElement = findUpClassName(spoiler, 'spoilers-container') || spoiler.parentElement;\n\n const className = 'is-spoiler-visible';\n const isVisible = parentElement.classList.contains(className);\n if(!isVisible) {\n cancelEvent(e);\n\n if(CLICK_EVENT_NAME !== 'click') {\n window.addEventListener('click', cancelEvent, {capture: true, once: true});\n }\n }\n\n const duration = 400 / 2;\n const showDuration = 5000;\n const useRafs = !isVisible ? 2 : 0;\n if(useRafs) {\n parentElement.classList.add('will-change');\n }\n\n const spoilerTimeout = parentElement.dataset.spoilerTimeout;\n if(spoilerTimeout !== null) {\n clearTimeout(+spoilerTimeout);\n delete parentElement.dataset.spoilerTimeout;\n }\n\n SetTransition({\n element: parentElement,\n className,\n forwards: true,\n duration,\n onTransitionEnd: () => {\n parentElement.dataset.spoilerTimeout = '' + window.setTimeout(() => {\n SetTransition({\n element: parentElement,\n className,\n forwards: false,\n duration,\n onTransitionEnd: () => {\n parentElement.classList.remove('will-change');\n delete parentElement.dataset.spoilerTimeout;\n }\n });\n }, showDuration);\n },\n useRafs\n });\n };\n\n document.addEventListener('mousemove', (e) => {\n const mediaStickerWrapper = findUpClassName(e.target, 'media-sticker-wrapper');\n if(!mediaStickerWrapper ||\n mediaStickerWrapper.classList.contains('custom-emoji') ||\n findUpClassName(e.target, 'emoji-big')) {\n return;\n }\n\n const animations = animationIntersector.getAnimations(mediaStickerWrapper);\n animations?.forEach((animationItem) => {\n const {liteModeKey, animation} = animationItem;\n if(!liteModeKey || !animation?.paused || liteMode.isAvailable(liteModeKey)) {\n return;\n }\n\n if(animation instanceof RLottiePlayer) {\n animation.playOrRestart();\n } else {\n animation.play();\n }\n });\n });\n\n rootScope.addEventListener('sticker_updated', ({type, faved}) => {\n if(type === 'faved') {\n toastNew({\n langPackKey: faved ? 'AddedToFavorites' : 'RemovedFromFavorites'\n });\n } else if(!faved) {\n toastNew({\n langPackKey: 'RemovedFromRecent'\n });\n }\n });\n\n apiManagerProxy.addEventListener('notificationBuild', async(options) => {\n const isForum = await this.managers.appPeersManager.isForum(options.message.peerId);\n const threadId = getMessageThreadId(options.message, isForum);\n if(this.chat.peerId === options.message.peerId && this.chat.threadId === threadId && !idleController.isIdle) {\n return;\n }\n\n uiNotificationsManager.buildNotification(options);\n });\n\n this.addEventListener('peer_changed', async({peerId}) => {\n document.body.classList.toggle('has-chat', !!peerId);\n\n this.emojiAnimationContainer.textContent = '';\n\n this.overrideHash(peerId);\n\n apiManagerProxy.updateTabState('chatPeerIds', this.chats.map((chat) => chat.peerId).filter(Boolean));\n });\n\n // stateStorage.get('chatPositions').then((c) => {\n stateStorage.setToCache('chatPositions', /* c || */{});\n // });\n\n if(IS_CALL_SUPPORTED || IS_GROUP_CALL_SUPPORTED) {\n this.topbarCall = new TopbarCall(managers);\n }\n\n if(IS_CALL_SUPPORTED) {\n callsController.addEventListener('instance', ({instance/* , hasCurrent */}) => {\n // if(hasCurrent) {\n // return;\n // }\n\n const popup = PopupElement.createPopup(PopupCall, instance);\n\n instance.addEventListener('acceptCallOverride', () => {\n return this.discardCurrentCall(instance.interlocutorUserId.toPeerId(), undefined, instance)\n .then(() => {\n callsController.dispatchEvent('accepting', instance);\n return true;\n })\n .catch(() => false);\n });\n\n popup.addEventListener('close', () => {\n const currentCall = callsController.currentCall;\n if(currentCall && currentCall !== instance && !instance.wasTryingToJoin) {\n instance.hangUp('phoneCallDiscardReasonBusy');\n }\n }, {once: true});\n\n popup.show();\n });\n\n callsController.addEventListener('incompatible', async(userId) => {\n toastNew({\n langPackKey: 'VoipPeerIncompatible',\n langPackArguments: [\n await wrapPeerTitle({peerId: userId.toPeerId()})\n ]\n });\n });\n }\n\n // ! do not remove this line\n // ! instance can be deactivated before the UI starts, because it waits in background for RAF that is delayed\n singleInstance.activateInstance();\n\n const setAuthorized = () => {\n telegramMeWebManager.setAuthorized(true);\n };\n\n setInterval(setAuthorized, ONE_DAY);\n setAuthorized();\n\n addAnchorListener<{}>({\n name: 'showMaskedAlert',\n callback: (params, element) => {\n const href = element.href;\n\n const a = element.cloneNode(true) as HTMLAnchorElement;\n a.className = 'anchor-url';\n a.innerText = href;\n a.removeAttribute('onclick');\n\n PopupElement.createPopup(PopupPeer, 'popup-masked-url', {\n titleLangKey: 'OpenUrlTitle',\n descriptionLangKey: 'OpenUrlAlert2',\n descriptionLangArgs: [a],\n buttons: [{\n langKey: 'Open',\n callback: () => {\n a.click();\n }\n }]\n }).show();\n }\n });\n\n addAnchorListener<{uriParams: {command: string, bot: string}}>({\n name: 'execBotCommand',\n callback: ({uriParams}) => {\n const {command, bot} = uriParams;\n\n /* const promise = bot ? this.openUsername(bot).then(() => this.chat.peerId) : Promise.resolve(this.chat.peerId);\n promise.then((peerId) => {\n this.managers.appMessagesManager.sendText(peerId, '/' + command);\n }); */\n\n this.managers.appMessagesManager.sendText(this.chat.peerId, '/' + command + (bot ? '@' + bot : ''));\n\n // console.log(command, bot);\n }\n });\n\n addAnchorListener<{uriParams: {hashtag: string}}>({\n name: 'searchByHashtag',\n callback: ({uriParams}) => {\n const {hashtag} = uriParams;\n if(!hashtag) {\n return;\n }\n\n this.chat.initSearch('#' + hashtag + ' ');\n }\n });\n\n addAnchorListener<{}>({\n name: 'setMediaTimestamp',\n callback: (_, element) => {\n const timestamp = +element.dataset.timestamp;\n const bubble = findUpClassName(element, 'bubble');\n if(bubble) {\n this.chat.bubbles.playMediaWithTimestamp(element, timestamp);\n return;\n }\n\n if(findUpClassName(element, 'media-viewer-caption')) {\n const appMediaViewer = (window as any).appMediaViewer;\n appMediaViewer.setMediaTimestamp(timestamp);\n }\n }\n });\n\n ([\n ['addstickers', INTERNAL_LINK_TYPE.STICKER_SET],\n ['addemoji', INTERNAL_LINK_TYPE.EMOJI_SET]\n ] as [\n 'addstickers' | 'addemoji',\n INTERNAL_LINK_TYPE.STICKER_SET | INTERNAL_LINK_TYPE.EMOJI_SET\n ][]).forEach(([name, type]) => {\n addAnchorListener<{pathnameParams: [typeof name, string]}>({\n name,\n callback: ({pathnameParams}) => {\n if(!pathnameParams[1]) {\n return;\n }\n\n const link: InternalLink = {\n _: type,\n set: pathnameParams[1]\n };\n\n this.processInternalLink(link);\n }\n });\n\n addAnchorListener<{\n uriParams: {\n set: string\n }\n }>({\n name,\n protocol: 'tg',\n callback: ({uriParams}) => {\n const link = this.makeLink(type, uriParams);\n this.processInternalLink(link);\n }\n });\n });\n\n // * t.me/invoice/asdasdad\n // * t.me/$asdasdad\n addAnchorListener<{pathnameParams: ['invoice', string] | string}>({\n name: 'invoice',\n callback: ({pathnameParams}) => {\n const link: InternalLink = {\n _: INTERNAL_LINK_TYPE.INVOICE,\n slug: pathnameParams.length > 1 ? pathnameParams[1] : pathnameParams[0].slice(1)\n };\n\n this.processInternalLink(link);\n }\n });\n\n // Support old t.me/joinchat/asd and new t.me/+asd\n addAnchorListener<{pathnameParams: ['joinchat', string]}>({\n name: 'joinchat',\n callback: ({pathnameParams}) => {\n const link: InternalLink = {\n _: INTERNAL_LINK_TYPE.JOIN_CHAT,\n invite: pathnameParams[1] || decodeURIComponent(pathnameParams[0]).slice(1)\n };\n\n this.processInternalLink(link);\n }\n });\n\n if(IS_GROUP_CALL_SUPPORTED) {\n addAnchorListener<{\n uriParams: Omit<InternalLink.InternalLinkVoiceChat, '_'>\n }>({\n name: 'voicechat',\n protocol: 'tg',\n callback: ({uriParams}) => {\n const link = this.makeLink(INTERNAL_LINK_TYPE.VOICE_CHAT, uriParams);\n this.processInternalLink(link);\n }\n });\n }\n\n type K1 = {thread?: string, comment?: string, t?: string};\n type K2 = {thread?: string, comment?: string, start?: string, t?: string};\n type K3 = {startattach?: string, attach?: string, choose?: string};\n\n addAnchorListener<{\n // pathnameParams: ['c', string, string],\n // uriParams: {thread?: number}\n // } | {\n // pathnameParams: [string, string?],\n // uriParams: {comment?: number}\n pathnameParams: ['c', string, string] | [string, string?],\n uriParams: K1 | K2 | K3\n }>({\n name: 'im',\n callback: async({pathnameParams, uriParams}, element) => {\n let link: InternalLink;\n if(PHONE_NUMBER_REG_EXP.test(pathnameParams[0])) {\n link = {\n _: INTERNAL_LINK_TYPE.USER_PHONE_NUMBER,\n phone: pathnameParams[0].slice(1)\n };\n } else if(pathnameParams[0] === 'c') {\n assumeType<K1>(uriParams);\n pathnameParams.shift();\n const thread = 'thread' in uriParams ? uriParams.thread : pathnameParams[2] && pathnameParams[1];\n link = {\n _: INTERNAL_LINK_TYPE.PRIVATE_POST,\n channel: pathnameParams[0],\n post: pathnameParams[2] || pathnameParams[1],\n thread,\n comment: uriParams.comment,\n stack: this.getStackFromElement(element),\n t: uriParams.t\n };\n } else {\n assumeType<K2>(uriParams);\n const thread = 'thread' in uriParams ? uriParams.thread : pathnameParams[2] && pathnameParams[1];\n link = {\n _: INTERNAL_LINK_TYPE.MESSAGE,\n domain: pathnameParams[0],\n post: pathnameParams[2] || pathnameParams[1],\n thread,\n comment: uriParams.comment,\n start: 'start' in uriParams ? uriParams.start : undefined,\n stack: this.getStackFromElement(element),\n t: uriParams.t\n };\n }\n\n if('startattach' in uriParams || 'attach' in uriParams) {\n assumeType<K3>(uriParams);\n link = {\n _: INTERNAL_LINK_TYPE.ATTACH_MENU_BOT,\n nestedLink: link,\n ...uriParams\n };\n }\n\n this.processInternalLink(link);\n }\n });\n\n addAnchorListener<{\n uriParams: {\n domain: string,\n\n // telegrampassport\n scope?: string,\n nonce?: string,\n payload?: string,\n bot_id?: string,\n public_key?: string,\n callback_url?: string,\n\n // regular\n start?: string,\n startgroup?: string,\n game?: string,\n voicechat?: string,\n post?: string,\n thread?: string,\n comment?: string,\n phone?: string,\n t?: string,\n attach?: string,\n startattach?: string,\n choose?: string\n }\n }>({\n name: 'resolve',\n protocol: 'tg',\n callback: ({uriParams}, element) => {\n let link: InternalLink;\n if(uriParams.phone) {\n link = this.makeLink(INTERNAL_LINK_TYPE.USER_PHONE_NUMBER, uriParams as Required<typeof uriParams>);\n } else if(uriParams.domain === 'telegrampassport') {\n\n } else {\n link = this.makeLink(INTERNAL_LINK_TYPE.MESSAGE, {\n ...uriParams,\n stack: this.getStackFromElement(element)\n });\n }\n\n if(uriParams.attach !== undefined || uriParams.startattach !== undefined) {\n const nestedLink = link;\n link = this.makeLink(INTERNAL_LINK_TYPE.ATTACH_MENU_BOT, uriParams as Required<typeof uriParams>);\n link.nestedLink = nestedLink;\n }\n\n this.processInternalLink(link);\n }\n });\n\n addAnchorListener<{\n uriParams: {\n channel: string,\n post: string,\n thread?: string,\n comment?: string\n }\n }>({\n name: 'privatepost',\n protocol: 'tg',\n callback: ({uriParams}) => {\n const link = this.makeLink(INTERNAL_LINK_TYPE.PRIVATE_POST, uriParams);\n this.processInternalLink(link);\n }\n });\n\n addAnchorListener<{\n uriParams: {\n slug: string\n }\n }>({\n name: 'invoice',\n protocol: 'tg',\n callback: ({uriParams}) => {\n const link = this.makeLink(INTERNAL_LINK_TYPE.INVOICE, uriParams);\n this.processInternalLink(link);\n }\n });\n\n ['joinchat' as const, 'join' as const].forEach((name) => {\n addAnchorListener<{\n uriParams: {\n invite: string\n }\n }>({\n name,\n protocol: 'tg',\n callback: ({uriParams}) => {\n const link = this.makeLink(INTERNAL_LINK_TYPE.JOIN_CHAT, uriParams);\n this.processInternalLink(link);\n }\n });\n });\n\n this.onHashChange(true);\n this.attachKeydownListener();\n this.handleAutologinDomains();\n this.checkForShare();\n }\n\n private checkForShare() {\n const share = apiManagerProxy.share;\n if(share) {\n apiManagerProxy.share = undefined;\n PopupElement.createPopup(PopupForward, undefined, async(peerId) => {\n await this.setPeer({peerId});\n if(share.files?.length) {\n const foundMedia = share.files.some((file) => MEDIA_MIME_TYPES_SUPPORTED.has(file.type));\n PopupElement.createPopup(PopupNewMedia, this.chat, share.files, foundMedia ? 'media' : 'document');\n } else {\n this.managers.appMessagesManager.sendText(peerId, share.text);\n }\n });\n }\n }\n\n public handleUrlAuth(options: {\n peerId?: PeerId,\n mid?: number,\n buttonId?: number,\n url: string\n }) {\n const {peerId, mid, buttonId, url} = options;\n\n const openWindow = (url: string) => {\n window.open(url, '_blank');\n };\n\n const onUrlAuthResultAccepted = (urlAuthResult: UrlAuthResult.urlAuthResultAccepted) => {\n openWindow(urlAuthResult.url);\n };\n\n const onUrlAuthResult = async(urlAuthResult: UrlAuthResult): Promise<void> => {\n if(urlAuthResult._ === 'urlAuthResultRequest') {\n const b = document.createElement('b');\n b.append(urlAuthResult.domain);\n const peerTitle = await wrapPeerTitle({peerId: rootScope.myId});\n const botPeerTitle = await wrapPeerTitle({peerId: urlAuthResult.bot.id.toPeerId()});\n\n const logInCheckbox: PopupPeerCheckboxOptions = {\n text: 'OpenUrlOption1',\n textArgs: [b.cloneNode(true), peerTitle],\n checked: true\n };\n\n const allowMessagesCheckbox: PopupPeerCheckboxOptions = urlAuthResult.pFlags.request_write_access ? {\n text: 'OpenUrlOption2',\n textArgs: [botPeerTitle],\n checked: true\n } : undefined;\n\n const checkboxes: PopupPeerCheckboxOptions[] = [\n logInCheckbox,\n allowMessagesCheckbox\n ];\n\n const confirmationPromise = confirmationPopup({\n titleLangKey: 'OpenUrlTitle',\n button: {\n langKey: 'Open'\n },\n descriptionLangKey: 'OpenUrlAlert2',\n descriptionLangArgs: [b],\n checkboxes: checkboxes.filter(Boolean)\n });\n\n if(allowMessagesCheckbox) {\n logInCheckbox.checkboxField.input.addEventListener('change', () => {\n const disabled = !logInCheckbox.checkboxField.checked;\n allowMessagesCheckbox.checkboxField.toggleDisability(disabled);\n\n if(disabled) {\n allowMessagesCheckbox.checkboxField.checked = false;\n }\n });\n }\n\n const [logInChecked, allowMessagesChecked] = await confirmationPromise;\n\n if(!logInChecked) {\n openWindow(url);\n return;\n }\n\n const result = await this.managers.appSeamlessLoginManager.acceptUrlAuth(\n url,\n peerId,\n mid,\n buttonId,\n allowMessagesChecked\n );\n\n return onUrlAuthResult(result);\n } else if(urlAuthResult._ === 'urlAuthResultAccepted') {\n onUrlAuthResultAccepted(urlAuthResult);\n } else {\n openWindow(url);\n }\n };\n\n return this.managers.appSeamlessLoginManager.requestUrlAuth(\n url,\n peerId,\n mid,\n buttonId\n ).then((urlAuthResult) => {\n onUrlAuthResult(urlAuthResult);\n });\n }\n\n private handleAutologinDomains() {\n let appConfig: MTAppConfig, config: Config.config;\n rootScope.addEventListener('app_config', (_appConfig) => {\n appConfig = _appConfig;\n });\n\n rootScope.addEventListener('config', (_config) => {\n config = _config;\n });\n\n const onAnchorClick = (element: HTMLAnchorElement) => {\n const url = new URL(element.href);\n if(appConfig.url_auth_domains.includes(url.hostname)) {\n this.handleUrlAuth({url: element.href});\n cancelEvent();\n return;\n }\n\n const autologinToken = config.autologin_token;\n\n if(!autologinToken || !appConfig.autologin_domains) {\n return;\n }\n\n const originalUrl = element.dataset.originalUrl ??= element.href;\n if(appConfig.autologin_domains.includes(url.hostname)) {\n url.searchParams.set('autologin_token', autologinToken);\n element.href = url.toString();\n\n setTimeout(() => {\n element.href = originalUrl;\n delete element.dataset.originalUrl;\n }, 0);\n }\n };\n\n document.addEventListener('click', (e) => {\n const anchor = findUpTag(e.target as HTMLElement, 'A') as HTMLAnchorElement;\n if(anchor?.href) {\n onAnchorClick(anchor);\n }\n });\n\n // addAnchorListener({\n // name: 'handleUrlClick',\n // callback: (_, element) => {\n // onAnchorClick(element);\n // },\n // noCancelEvent: true,\n // noPathnameParams: true,\n // noUriParams: true\n // });\n }\n\n private getStackFromElement(element: HTMLElement) {\n const possibleBubble = findUpClassName(element, 'bubble');\n return possibleBubble ? +possibleBubble.dataset.mid : undefined;\n }\n\n private deleteFilesIterative(callback: (response: Response) => boolean) {\n return this.cacheStorage.timeoutOperation((cache) => {\n const perf = performance.now();\n return cache.keys().then((requests) => {\n const promises = requests.map((request) => {\n return cache.match(request).then((response) => {\n return callback(response);\n });\n });\n\n return Promise.all(promises).then((values) => {\n values.map((isBad, idx) => {\n if(!isBad) {\n return;\n }\n\n const request = requests[idx];\n return cache.delete(request);\n });\n\n return Promise.all(values.filter(Boolean));\n });\n }).then(() => {\n this.log('deleted files', performance.now() - perf);\n });\n });\n }\n\n private toggleChatGradientAnimation(activatingChat: Chat) {\n this.chats.forEach((chat) => {\n if(chat.gradientRenderer) {\n chat.gradientRenderer.scrollAnimate(liteMode.isAvailable('animations') && chat === activatingChat);\n }\n });\n }\n\n private appendEmojiAnimationContainer(screen: ScreenSize) {\n const appendTo = screen === ScreenSize.mobile ? this.columnEl : document.body;\n if(this.emojiAnimationContainer.parentElement !== appendTo) {\n appendTo.append(this.emojiAnimationContainer)\n }\n }\n\n private attachKeydownListener() {\n const IGNORE_KEYS = new Set(['PageUp', 'PageDown', 'Meta', 'Control']);\n const onKeyDown = (e: KeyboardEvent) => {\n const key = e.key;\n const isSelectionCollapsed = document.getSelection().isCollapsed;\n if(overlayCounter.isOverlayActive || IGNORE_KEYS.has(key)) return;\n\n const target = e.target as HTMLElement;\n\n const isTargetAnInput = (target.tagName === 'INPUT' && !['checkbox', 'radio'].includes((target as HTMLInputElement).type)) || target.isContentEditable;\n\n // if(target.tagName === 'INPUT') return;\n\n // this.log('onkeydown', e, document.activeElement);\n\n const chat = this.chat;\n\n if((key.startsWith('Arrow') || (e.shiftKey && key === 'Shift')) && !isSelectionCollapsed) {\n return;\n } else if(e.code === 'KeyC' && (e.ctrlKey || e.metaKey) && !isTargetAnInput) {\n return;\n } else if(e.altKey && (key === 'ArrowUp' || key === 'ArrowDown')) {\n cancelEvent(e);\n this.managers.dialogsStorage.getNextDialog(this.chat.peerId, key === 'ArrowDown', appDialogsManager.filterId).then((dialog) => {\n if(dialog) {\n this.setPeer({peerId: dialog.peerId});\n }\n });\n } else if(key === 'ArrowUp' && this.chat.type !== 'scheduled') {\n if(!chat.input.editMsgId && chat.input.isInputEmpty()) {\n this.managers.appMessagesManager.getFirstMessageToEdit(chat.peerId, chat.threadId).then((message) => {\n if(message) {\n chat.input.initMessageEditing(message.mid);\n cancelEvent(e); // * prevent from scrolling\n }\n });\n } else {\n return;\n }\n } else if(key === 'ArrowDown') {\n return;\n }\n\n if(\n chat?.input?.messageInput &&\n target !== chat.input.messageInput &&\n !isTargetAnInput &&\n !IS_TOUCH_SUPPORTED &&\n (!mediaSizes.isMobile || this.tabId === APP_TABS.CHAT) &&\n !chat.selection.isSelecting &&\n !chat.input.recording &&\n chat.input.messageInput.isContentEditable\n ) {\n chat.input.messageInput.focus();\n placeCaretAtEnd(chat.input.messageInput);\n\n // clone and dispatch same event to new input. it is needed for sending message if input was blurred\n const newEvent = new KeyboardEvent(e.type, e);\n chat.input.messageInput.dispatchEvent(newEvent);\n }\n };\n\n document.body.addEventListener('keydown', onKeyDown);\n }\n\n private makeLink<T extends INTERNAL_LINK_TYPE>(type: T, uriParams: Omit<InternalLinkTypeMap[T], '_'>) {\n return {\n _: type,\n ...uriParams\n } as any as InternalLinkTypeMap[T];\n }\n\n public async processInternalLink(link: InternalLink) {\n switch(link?._) {\n case INTERNAL_LINK_TYPE.MESSAGE: {\n const postId = link.post ? generateMessageId(+link.post) : undefined;\n const commentId = link.comment ? generateMessageId(+link.comment) : undefined;\n const threadId = link.thread ? generateMessageId(+link.thread) : undefined;\n\n this.openUsername({\n userName: link.domain,\n lastMsgId: postId,\n commentId,\n startParam: link.start,\n stack: link.stack,\n threadId,\n mediaTimestamp: link.t && +link.t\n });\n break;\n }\n\n case INTERNAL_LINK_TYPE.PRIVATE_POST: {\n const chatId = link.channel.toChatId();\n const peerId = chatId.toPeerId(true);\n\n const chat = await this.managers.appChatsManager.getChat(chatId);\n if(!chat) {\n try {\n await this.managers.appChatsManager.resolveChannel(chatId);\n } catch(err) {\n toastNew({langPackKey: 'LinkNotFound'});\n throw err;\n }\n }\n\n const postId = generateMessageId(+link.post);\n const threadId = link.thread ? generateMessageId(+link.thread) : undefined;\n\n this.op({\n peer: chat,\n lastMsgId: postId,\n threadId,\n stack: link.stack,\n mediaTimestamp: link.t && +link.t\n });\n break;\n }\n\n case INTERNAL_LINK_TYPE.EMOJI_SET:\n case INTERNAL_LINK_TYPE.STICKER_SET: {\n PopupElement.createPopup(PopupStickers, {id: link.set}, link._ === INTERNAL_LINK_TYPE.EMOJI_SET).show();\n break;\n }\n\n case INTERNAL_LINK_TYPE.JOIN_CHAT: {\n this.managers.appChatsManager.checkChatInvite(link.invite).then((chatInvite) => {\n if((chatInvite as ChatInvite.chatInvitePeek).chat) {\n this.managers.appChatsManager.saveApiChat((chatInvite as ChatInvite.chatInvitePeek).chat, true);\n }\n\n // console.log(chatInvite);\n\n if(chatInvite._ === 'chatInviteAlready' ||\n chatInvite._ === 'chatInvitePeek'/* && chatInvite.expires > tsNow(true) */) {\n this.setInnerPeer({\n peerId: chatInvite.chat.id.toPeerId(true)\n });\n return;\n }\n\n PopupElement.createPopup(PopupJoinChatInvite, link.invite, chatInvite);\n }, (err) => {\n if(err.type === 'INVITE_HASH_EXPIRED') {\n toast(i18n('InviteExpired'));\n }\n });\n break;\n }\n\n case INTERNAL_LINK_TYPE.VOICE_CHAT: {\n if(IS_GROUP_CALL_SUPPORTED) {\n this.joinGroupCall(link.chat_id.toPeerId(true), link.id);\n }\n\n break;\n }\n\n case INTERNAL_LINK_TYPE.USER_PHONE_NUMBER: {\n this.managers.appUsersManager.resolvePhone(link.phone).then((user) => {\n this.setInnerPeer({\n peerId: user.id.toPeerId(false)\n });\n }).catch((err) => {\n if(err.type === 'PHONE_NOT_OCCUPIED') {\n toastNew({langPackKey: 'Alert.UserDoesntExists'});\n }\n });\n\n break;\n }\n\n case INTERNAL_LINK_TYPE.INVOICE: {\n this.managers.appPaymentsManager.getInputInvoiceBySlug(link.slug).then((inputInvoice) => {\n this.managers.appPaymentsManager.getPaymentForm(inputInvoice).then((paymentForm) => {\n // const message: Message.message = {\n // _: 'message',\n // date: 0,\n // id: 0,\n // peerId: 0,\n // peer_id: undefined,\n // message: '',\n // media: {\n // _: 'messageMediaInvoice',\n // currency: paymentForm.invoice.currency,\n // description: paymentForm.description,\n\n // }\n // };\n PopupElement.createPopup(PopupPayment, undefined, inputInvoice, paymentForm);\n });\n });\n break;\n }\n\n case INTERNAL_LINK_TYPE.ATTACH_MENU_BOT: {\n console.log(link);\n const botUsername = link.attach || link.domain;\n const user = await this.managers.appUsersManager.resolveUserByUsername(botUsername).catch(() => undefined as User.user);\n\n if(link.attach !== undefined) {\n this.processInternalLink(link.nestedLink);\n }\n\n let errorLangPackKey: LangPackKey;\n if(!user) {\n errorLangPackKey = 'Alert.UserDoesntExists';\n } else if(!user.pFlags.bot_attach_menu) {\n errorLangPackKey = 'BotCantAddToAttachMenu';\n }/* else if(user.pFlags.attach_menu_enabled) {\n errorLangPackKey = 'BotAlreadyAddedToAttachMenu';\n } */\n\n if(errorLangPackKey) {\n toastNew({langPackKey: errorLangPackKey});\n break;\n }\n\n const peerId = user.id.toPeerId(false);\n const attachMenuBot = await this.managers.appAttachMenuBotsManager.getAttachMenuBot(user.id);\n\n console.log(attachMenuBot);\n\n if(attachMenuBot.pFlags.inactive) {\n const haveWriteAccess = await confirmationPopup({\n button: {\n text: 'Add'\n },\n descriptionLangKey: 'BotRequestAttachPermission',\n descriptionLangArgs: [await wrapPeerTitle({peerId})],\n checkbox: attachMenuBot.pFlags.request_write_access ? {\n text: 'OpenUrlOption2',\n textArgs: [await wrapPeerTitle({peerId})],\n checked: true\n } : undefined,\n peerId,\n titleLangKey: 'AddBot'\n });\n\n await this.managers.appAttachMenuBotsManager.toggleBotInAttachMenu(user.id, true, haveWriteAccess);\n }\n\n break;\n }\n\n default: {\n this.log.warn('Not supported internal link:', link);\n break;\n }\n }\n }\n\n public openUrl(url: string) {\n const {url: wrappedUrl, onclick} = wrapUrl(url);\n if(!onclick) {\n return;\n }\n\n const a = document.createElement('a');\n a.href = wrappedUrl;\n (window as any)[onclick](a);\n }\n\n private onHashChange = (saveState?: boolean) => {\n try {\n this.onHashChangeUnsafe(saveState);\n } catch(err) {\n this.log.error('hash change error', err);\n }\n };\n\n private onHashChangeUnsafe = (saveState?: boolean) => {\n const hash = location.hash;\n if(!saveState) {\n appNavigationController.replaceState();\n }\n\n const splitted = hash.split('?');\n const params = parseUriParams(hash, splitted);\n this.log('hashchange', hash, splitted[0], params);\n if(!hash) {\n return;\n }\n\n if(params.tgaddr) {\n this.openUrl(params.tgaddr);\n return;\n }\n\n switch(splitted[0]) {\n default: {\n params.p = splitted[0].slice(1);\n }\n\n case '#/im': {\n if(!Object.keys(params).length) {\n break;\n }\n\n const p: string = params.p;\n const postId = params.post !== undefined ? generateMessageId(+params.post) : undefined;\n\n switch(p[0]) {\n case '@': {\n this.openUsername({\n userName: p,\n lastMsgId: postId\n });\n break;\n }\n\n default: { // peerId\n this.setInnerPeer({\n peerId: postId ? p.toPeerId(true) : p.toPeerId(),\n lastMsgId: postId\n });\n break;\n }\n }\n }\n }\n\n // appNavigationController.replaceState();\n // location.hash = '';\n };\n\n private async op(options: {\n peer: User.user | MTChat\n } & Omit<ChatSetPeerOptions, 'peerId'>) {\n let {peer, commentId, threadId, lastMsgId} = options;\n const isUser = peer._ === 'user';\n const peerId = peer.id.toPeerId(!isUser);\n\n const isForum = peer._ === 'channel' && peer.pFlags.forum;\n // open forum tab\n if(!commentId && !threadId && !lastMsgId && isForum) {\n appDialogsManager.toggleForumTabByPeerId(peerId, true);\n return;\n }\n\n // handle t.me/username/thread or t.me/username/messageId\n if(isForum && lastMsgId && !threadId) {\n const message = await this.managers.appMessagesManager.reloadMessages(peerId, lastMsgId);\n if(message) {\n threadId = options.threadId = getMessageThreadId(message, isForum);\n } else {\n threadId = options.threadId = lastMsgId;\n lastMsgId = options.lastMsgId = undefined;\n }\n }\n\n if(threadId) {\n return this.openThread({\n ...(options as any as Parameters<AppImManager['openThread']>[0]),\n peerId\n });\n } else if(commentId) {\n return this.openComment({\n peerId,\n msgId: lastMsgId,\n commentId\n });\n }\n\n return this.setInnerPeer({\n ...options,\n peerId\n });\n }\n\n public openPremiumBot() {\n return this.managers.apiManager.getAppConfig().then((appConfig) => {\n return this.openUsername({userName: appConfig.premium_bot_username});\n });\n }\n\n public openUsername(options: {\n userName: string\n } & Omit<ChatSetPeerOptions, 'peerId'>) {\n const {userName} = options;\n return this.managers.appUsersManager.resolveUsername(userName).then((peer) => {\n return this.op({\n peer,\n ...options\n });\n }, (err: ApiError) => {\n if(err.type === 'USERNAME_NOT_OCCUPIED') {\n toastNew({langPackKey: 'NoUsernameFound'});\n } else if(err.type === 'USERNAME_INVALID') {\n toastNew({langPackKey: 'Alert.UserDoesntExists'});\n }\n });\n }\n\n /**\n * Opens thread when peerId of discussion group is known\n */\n public async openThread(options: {\n peerId: PeerId,\n lastMsgId: number,\n threadId: number,\n stack?: number\n }) {\n if(await this.managers.appChatsManager.isForum(options.peerId.toChatId())) {\n await this.managers.dialogsStorage.getForumTopicOrReload(options.peerId, options.threadId);\n return this.setInnerPeer(options);\n }\n\n return this.managers.appMessagesManager.reloadMessages(options.peerId, options.threadId).then((message) => {\n if(!message) {\n options.lastMsgId = undefined;\n } else {\n this.managers.appMessagesManager.generateThreadServiceStartMessage(message);\n }\n\n return this.setInnerPeer({\n ...options,\n type: 'discussion'\n });\n });\n }\n\n /**\n * Opens comment directly from original channel\n */\n public openComment(options: {\n peerId: PeerId,\n msgId: number,\n commentId: number\n }) {\n return this.managers.appMessagesManager.getDiscussionMessage(options.peerId, options.msgId).then((message) => {\n return this.openThread({\n peerId: message.peerId,\n lastMsgId: options.commentId,\n threadId: message.mid\n });\n });\n }\n\n public async callUser(userId: UserId, type: CallType) {\n const call = callsController.getCallByUserId(userId);\n if(call) {\n return;\n }\n\n const userFull = await this.managers.appProfileManager.getProfile(userId);\n if(userFull.pFlags.phone_calls_private) {\n wrapPeerTitle({peerId: userId.toPeerId()}).then((element) => {\n return confirmationPopup({\n descriptionLangKey: 'Call.PrivacyErrorMessage',\n descriptionLangArgs: [element],\n button: {\n langKey: 'OK',\n isCancel: true\n }\n });\n });\n\n return;\n }\n\n await this.discardCurrentCall(userId.toPeerId());\n\n callsController.startCallInternal(userId, type === 'video');\n }\n\n private discardCurrentCall(toPeerId: PeerId, ignoreGroupCall?: GroupCallInstance, ignoreCall?: CallInstance) {\n if(groupCallsController.groupCall && groupCallsController.groupCall !== ignoreGroupCall) return this.discardGroupCallConfirmation(toPeerId);\n else if(callsController.currentCall && callsController.currentCall !== ignoreCall) return this.discardCallConfirmation(toPeerId);\n else return Promise.resolve();\n }\n\n private async discardCallConfirmation(toPeerId: PeerId) {\n const currentCall = callsController.currentCall;\n if(currentCall) {\n await Promise.all([\n wrapPeerTitle({peerId: currentCall.interlocutorUserId.toPeerId(false)}),\n wrapPeerTitle({peerId: toPeerId})\n ]).then(([title1, title2]) => {\n return confirmationPopup({\n titleLangKey: 'Call.Confirm.Discard.Call.Header',\n descriptionLangKey: toPeerId.isUser() ? 'Call.Confirm.Discard.Call.ToCall.Text' : 'Call.Confirm.Discard.Call.ToVoice.Text',\n descriptionLangArgs: [title1, title2],\n button: {\n langKey: 'OK'\n }\n });\n });\n\n if(!currentCall.isClosing) {\n await currentCall.hangUp('phoneCallDiscardReasonDisconnect');\n }\n }\n }\n\n private async discardGroupCallConfirmation(toPeerId: PeerId) {\n const currentGroupCall = groupCallsController.groupCall;\n if(currentGroupCall) {\n await Promise.all([\n wrapPeerTitle({peerId: currentGroupCall.chatId.toPeerId(true)}),\n wrapPeerTitle({peerId: toPeerId})\n ]).then(([title1, title2]) => {\n return confirmationPopup({\n titleLangKey: 'Call.Confirm.Discard.Voice.Header',\n descriptionLangKey: toPeerId.isUser() ? 'Call.Confirm.Discard.Voice.ToCall.Text' : 'Call.Confirm.Discard.Voice.ToVoice.Text',\n descriptionLangArgs: [title1, title2],\n button: {\n langKey: 'OK'\n }\n });\n });\n\n if(groupCallsController.groupCall === currentGroupCall) {\n await currentGroupCall.hangUp();\n }\n }\n }\n\n public async joinGroupCall(peerId: PeerId, groupCallId?: GroupCallId) {\n const chatId = peerId.toChatId();\n const hasRights = this.managers.appChatsManager.hasRights(chatId, 'manage_call');\n const next = async() => {\n const chatFull = await this.managers.appProfileManager.getChatFull(chatId);\n let call: MyGroupCall;\n if(!chatFull.call) {\n if(!hasRights) {\n return;\n }\n\n call = await this.managers.appGroupCallsManager.createGroupCall(chatId);\n } else {\n call = chatFull.call;\n }\n\n groupCallsController.joinGroupCall(chatId, call.id, true, false);\n };\n\n if(groupCallId) {\n const groupCall = await this.managers.appGroupCallsManager.getGroupCallFull(groupCallId);\n if(groupCall._ === 'groupCallDiscarded') {\n if(!hasRights) {\n toastNew({\n langPackKey: 'VoiceChat.Chat.Ended'\n });\n\n return;\n }\n\n await confirmationPopup({\n descriptionLangKey: 'VoiceChat.Chat.StartNew',\n button: {\n langKey: 'VoiceChat.Chat.StartNew.OK'\n }\n });\n }\n }\n\n // await this.discardCurrentCall(peerId);\n\n next();\n };\n\n public setCurrentBackground(broadcastEvent = false): ReturnType<AppImManager['setBackground']> {\n const theme = themeController.getTheme();\n\n const slug = (theme.settings?.wallpaper as WallPaper.wallPaper)?.slug;\n if(slug) {\n const defaultTheme = STATE_INIT.settings.themes.find((t) => t.name === theme.name);\n // const isDefaultBackground = theme.background.blur === defaultTheme.background.blur &&\n // slug === defaultslug;\n\n // if(!isDefaultBackground) {\n return this.getBackground(slug).then((url) => {\n return this.setBackground(url, broadcastEvent);\n }, () => { // * if NO_ENTRY_FOUND\n theme.settings = copy(defaultTheme.settings); // * reset background\n return this.setCurrentBackground(true);\n });\n // }\n }\n\n return this.setBackground('', broadcastEvent);\n }\n\n private getBackground(slug: string) {\n if(this.backgroundPromises[slug]) return this.backgroundPromises[slug];\n return this.backgroundPromises[slug] = this.cacheStorage.getFile('backgrounds/' + slug).then((blob) => {\n return URL.createObjectURL(blob);\n });\n }\n\n public setBackground(url: string, broadcastEvent = true): Promise<void> {\n this.lastBackgroundUrl = url;\n const promises = this.chats.map((chat) => chat.setBackground(url));\n return promises[promises.length - 1].then(() => {\n if(broadcastEvent) {\n rootScope.dispatchEvent('background_change');\n }\n });\n }\n\n public saveChatPosition(chat: Chat) {\n if(!(['chat', 'discussion'] as ChatType[]).includes(chat.type) || !chat.peerId) {\n return;\n }\n\n // const bubble = chat.bubbles.getBubbleByPoint('top');\n // if(bubble) {\n // const top = bubble.getBoundingClientRect().top;\n const chatBubbles = chat.bubbles;\n const key = chat.peerId + (chat.threadId ? '_' + chat.threadId : '');\n const chatPositions = stateStorage.getFromCache('chatPositions');\n if(!(chatBubbles.scrollable.getDistanceToEnd() <= 16 && chatBubbles.scrollable.loadedAll.bottom) && chatBubbles.getRenderedLength()) {\n chatBubbles.sliceViewport(true);\n const top = chatBubbles.scrollable.scrollTop;\n\n const position = {\n mids: getObjectKeysAndSort(chatBubbles.bubbles, 'desc').filter((mid) => mid > 0 && !chatBubbles.skippedMids.has(mid)),\n top\n };\n\n chatPositions[key] = position;\n\n this.log('saved chat position:', position);\n } else {\n delete chatPositions[key];\n\n this.log('deleted chat position');\n }\n\n stateStorage.set({chatPositions}, true);\n // }\n }\n\n public getChatSavedPosition(chat: Chat): ChatSavedPosition {\n if(!(['chat', 'discussion'] as ChatType[]).includes(chat.type) || !chat.peerId) {\n return;\n }\n\n const key = chat.peerId + (chat.threadId ? '_' + chat.threadId : '');\n const cache = stateStorage.getFromCache('chatPositions');\n return cache && cache[key];\n }\n\n public applyCurrentTheme(slug?: string, backgroundUrl?: string, broadcastEvent?: boolean) {\n if(backgroundUrl) {\n this.backgroundPromises[slug] = Promise.resolve(backgroundUrl);\n }\n\n themeController.setTheme();\n\n return this.setCurrentBackground(broadcastEvent === undefined ? !!slug : broadcastEvent);\n }\n\n private setSettings = () => {\n const {messagesTextSize} = rootScope.settings;\n\n this.customEmojiSize = makeMediaSize(messagesTextSize + 4, messagesTextSize + 4);\n document.documentElement.style.setProperty('--messages-text-size', messagesTextSize + 'px');\n\n const firstTime = !this.customEmojiSize;\n if(!firstTime) {\n const ellipsisElements = document.querySelectorAll<MiddleEllipsisElement>('middle-ellipsis-element');\n ellipsisElements.forEach((element) => {\n element.disconnectedCallback();\n element.dataset.fontSize = '' + messagesTextSize;\n if(element.title) element.textContent = element.title;\n element.connectedCallback();\n });\n\n const renderers = document.querySelectorAll<CustomEmojiRendererElement>('.chat custom-emoji-renderer-element');\n renderers.forEach((renderer) => {\n renderer.forceRenderAfterSize = true;\n });\n }\n\n document.body.classList.toggle('animation-level-0', !liteMode.isAvailable('animations'));\n document.body.classList.toggle('animation-level-1', false);\n document.body.classList.toggle('animation-level-2', liteMode.isAvailable('animations'));\n\n this.chatsSelectTabDebounced = debounce(() => {\n const topbar = this.chat.topbar;\n topbar.pinnedMessage?.setCorrectIndex(0); // * буду молиться богам, чтобы это ничего не сломало, но это исправляет получение пиннеда после анимации\n\n this.managers.apiFileManager.setQueueId(this.chat.bubbles.lazyLoadQueue.queueId);\n }, liteMode.isAvailable('animations') ? 250 : 0, false, true);\n\n const c: LiteModeKey[] = ['stickers_chat', 'stickers_panel'];\n const changedLoop = animationIntersector.setLoop(rootScope.settings.stickers.loop);\n const changedAutoplay = !!c.filter((key) => animationIntersector.setAutoplay(liteMode.isAvailable(key), key)).length;\n if(changedLoop || changedAutoplay) {\n animationIntersector.checkAnimations2(false);\n }\n\n for(const chat of this.chats) {\n chat.setAutoDownloadMedia();\n }\n\n I18n.setTimeFormat(rootScope.settings.timeFormat);\n\n this.toggleChatGradientAnimation(this.chat);\n };\n\n // * не могу использовать тут TransitionSlider, так как мне нужен отрисованный блок рядом\n // * (или под текущим чатом) чтобы правильно отрендерить чат (напр. scrollTop)\n private chatsSelectTab(tab: HTMLElement, animate?: boolean) {\n if(this.prevTab === tab) {\n return;\n }\n\n if(animate === false && this.prevTab) { // * will be used for Safari iOS history swipe\n disableTransition([tab, this.prevTab].filter(Boolean));\n }\n\n if(this.prevTab) {\n this.prevTab.classList.remove('active');\n this.chatsSelectTabDebounced();\n\n // ! нужно переделать на animation, так как при лаге анимация будет длиться не 250мс\n if(liteMode.isAvailable('animations') && animate !== false) {\n dispatchHeavyAnimationEvent(pause(250 + 150), 250 + 150);\n }\n\n const prevIdx = whichChild(this.prevTab);\n const idx = whichChild(tab);\n if(idx > prevIdx) {\n appNavigationController.pushItem({\n type: 'chat',\n onPop: (canAnimate) => {\n this.setPeer({}, canAnimate);\n blurActiveElement();\n }\n });\n }\n }\n\n tab.classList.add('active');\n this.prevTab = tab;\n }\n\n private init() {\n document.addEventListener('paste', this.onDocumentPaste, true);\n\n if(!IS_TOUCH_SUPPORTED) {\n this.attachDragAndDropListeners();\n }\n\n // if(!isTouchSupported) {\n this.markupTooltip = new MarkupTooltip(this);\n this.markupTooltip.handleSelection();\n // }\n }\n\n private attachDragAndDropListeners() {\n const drops: ChatDragAndDrop[] = [];\n const mediaDrops: ChatDragAndDrop[] = [];\n let mounted = false;\n const toggle = async(e: DragEvent, mount: boolean) => {\n if(mount === mounted) return;\n\n const _types = e.dataTransfer.types;\n // @ts-ignore\n const isFiles = _types.contains ? _types.contains('Files') : _types.indexOf('Files') >= 0;\n\n const newMediaPopup = getCurrentNewMediaPopup();\n const types: string[] = await getFilesFromEvent(e, true);\n if(!isFiles || (!(await this.canDrag()) && !newMediaPopup)) { // * skip dragging text case\n counter = 0;\n return;\n }\n\n const rights = await PopupNewMedia.canSend(this.chat.peerId, true);\n\n const _dropsContainer = newMediaPopup ? mediaDropsContainer : dropsContainer;\n const _drops = newMediaPopup ? mediaDrops : drops;\n\n if(mount && !_drops.length) {\n const force = isFiles && !types.length; // * can't get file items not from 'drop' on Safari\n\n const [foundMedia, foundDocuments] = partition(types, (t) => MEDIA_MIME_TYPES_SUPPORTED.has(t));\n const [foundPhotos, foundVideos] = partition(foundMedia, (t) => IMAGE_MIME_TYPES_SUPPORTED.has(t));\n\n if(!rights.send_docs) {\n foundDocuments.length = 0;\n } else {\n foundDocuments.push(...foundMedia);\n }\n\n if(!rights.send_photos) {\n foundPhotos.forEach((mimeType) => indexOfAndSplice(foundMedia, mimeType));\n foundPhotos.length = 0;\n }\n\n if(!rights.send_videos) {\n foundVideos.forEach((mimeType) => indexOfAndSplice(foundMedia, mimeType));\n foundVideos.length = 0;\n }\n\n this.log('drag files', types, foundMedia, foundDocuments, foundPhotos, foundVideos);\n\n if(newMediaPopup) {\n newMediaPopup.appendDrops(_dropsContainer);\n\n const length = (rights.send_docs ? [foundDocuments] : [foundPhotos, foundVideos]).reduce((acc, v) => acc + v.length, 0);\n if(length || force) {\n _drops.push(new ChatDragAndDrop(_dropsContainer, {\n header: 'Preview.Dragging.AddItems',\n headerArgs: [length],\n onDrop: (e: DragEvent) => {\n toggle(e, false);\n this.log('drop', e);\n this.onDocumentPaste(e, 'document');\n }\n }));\n }\n } else {\n if(foundDocuments.length || force) {\n _drops.push(new ChatDragAndDrop(_dropsContainer, {\n icon: 'dragfiles',\n header: 'Chat.DropTitle',\n subtitle: 'Chat.DropAsFilesDesc',\n onDrop: (e: DragEvent) => {\n toggle(e, false);\n this.log('drop', e);\n this.onDocumentPaste(e, 'document');\n }\n }));\n }\n\n if(foundMedia.length || force) {\n _drops.push(new ChatDragAndDrop(_dropsContainer, {\n icon: 'dragmedia',\n header: 'Chat.DropTitle',\n subtitle: 'Chat.DropQuickDesc',\n onDrop: (e: DragEvent) => {\n toggle(e, false);\n this.log('drop', e);\n this.onDocumentPaste(e, 'media');\n }\n }));\n }\n\n this.chat.container.append(_dropsContainer);\n }\n }\n\n // if(!mount) return;\n\n SetTransition({\n element: _dropsContainer,\n className: 'is-visible',\n forwards: mount,\n duration: 200,\n onTransitionEnd: () => {\n if(!mount) {\n _drops.forEach((drop) => {\n drop.destroy();\n });\n\n _drops.length = 0;\n }\n }\n });\n\n if(mount) {\n _drops.forEach((drop) => {\n drop.setPath();\n });\n } else {\n counter = 0;\n }\n\n document.body.classList.toggle('is-dragging', mount);\n mounted = mount;\n };\n\n /* document.body.addEventListener('dragover', (e) => {\n cancelEvent(e);\n }); */\n\n let counter = 0;\n document.body.addEventListener('dragenter', (e) => {\n counter++;\n });\n\n document.body.addEventListener('dragover', (e) => {\n // this.log('dragover', e/* , e.dataTransfer.types[0] */);\n toggle(e, true);\n cancelEvent(e);\n });\n\n document.body.addEventListener('dragleave', (e) => {\n // this.log('dragleave', e, counter);\n // if((e.pageX <= 0 || e.pageX >= this.managers.appPhotosManager.windowW) || (e.pageY <= 0 || e.pageY >= this.managers.appPhotosManager.windowH)) {\n counter--;\n if(counter === 0) {\n // if(!findUpClassName(e.target, 'drops-container')) {\n toggle(e, false);\n }\n });\n\n const dropsContainer = document.createElement('div');\n dropsContainer.classList.add('drops-container');\n\n const mediaDropsContainer = dropsContainer.cloneNode(true) as HTMLElement;\n }\n\n private async canDrag() {\n const chat = this.chat;\n const peerId = chat?.peerId;\n return !(!peerId || overlayCounter.isOverlayActive || !(await chat.canSend('send_media')));\n }\n\n private onDocumentPaste = async(e: ClipboardEvent | DragEvent, attachType?: 'media' | 'document') => {\n const newMediaPopup = getCurrentNewMediaPopup();\n\n // console.log('document paste');\n // console.log('item', event.clipboardData.getData());\n\n if(e instanceof DragEvent) {\n const _types = e.dataTransfer.types;\n // @ts-ignore\n const isFiles = _types.contains ? _types.contains('Files') : _types.indexOf('Files') >= 0;\n if(isFiles) {\n cancelEvent(e);\n }\n }\n\n const files = await getFilesFromEvent(e);\n if(!(await this.canDrag()) && !newMediaPopup) return;\n if(files.length) {\n if(newMediaPopup) {\n newMediaPopup.addFiles(files);\n return;\n }\n\n const chatInput = this.chat.input;\n chatInput.willAttachType = attachType || (MEDIA_MIME_TYPES_SUPPORTED.has(files[0].type) ? 'media' : 'document');\n PopupElement.createPopup(PopupNewMedia, this.chat, files, chatInput.willAttachType);\n }\n };\n\n private async overrideHash(peerId?: PeerId) {\n let str: string;\n if(peerId) {\n const username = await this.managers.appPeersManager.getPeerUsername(peerId);\n str = username ? '@' + username : '' + peerId;\n }\n\n appNavigationController.overrideHash(str);\n }\n\n public selectTab(id: APP_TABS, animate?: boolean) {\n if(animate === false) { // * will be used for Safari iOS history swipe\n disableTransition([appSidebarLeft.sidebarEl, this.columnEl, appSidebarRight.sidebarEl]);\n }\n\n document.body.classList.toggle(LEFT_COLUMN_ACTIVE_CLASSNAME, id === APP_TABS.CHATLIST);\n\n const prevTabId = this.tabId;\n if(prevTabId !== undefined) {\n this.overrideHash(id > APP_TABS.CHATLIST ? this.chat?.peerId : undefined);\n this.dispatchEvent('tab_changing', id);\n }\n\n this.log('selectTab', id, prevTabId);\n\n let animationPromise: Promise<any> = liteMode.isAvailable('animations') ? doubleRaf() : Promise.resolve();\n if(\n prevTabId !== undefined &&\n prevTabId !== id &&\n liteMode.isAvailable('animations') &&\n animate !== false/* &&\n mediaSizes.activeScreen !== ScreenSize.large */\n ) {\n const transitionTime = (mediaSizes.isMobile ? 250 : 200) + 100; // * cause transition time could be > 250ms\n animationPromise = pause(transitionTime);\n dispatchHeavyAnimationEvent(animationPromise, transitionTime);\n\n // ! it's very heavy operation. will blink in firefox\n /* this.columnEl.classList.add('disable-hover');\n animationPromise.finally(() => {\n this.columnEl.classList.remove('disable-hover');\n }); */\n }\n\n this.tabId = id;\n blurActiveElement();\n if(mediaSizes.isMobile && prevTabId === APP_TABS.PROFILE && id < APP_TABS.PROFILE) {\n document.body.classList.remove(RIGHT_COLUMN_ACTIVE_CLASSNAME);\n }\n\n if(prevTabId !== undefined && id > prevTabId) {\n if(id < APP_TABS.PROFILE || !appNavigationController.findItemByType('im')) {\n appNavigationController.pushItem({\n type: 'im',\n onPop: (canAnimate) => {\n // this.selectTab(prevTabId, !isSafari);\n this.setPeer({}, canAnimate);\n }\n });\n }\n }\n\n const onImTabChange = (window as any).onImTabChange;\n onImTabChange && onImTabChange(id);\n\n // this._selectTab(id, mediaSizes.isMobile);\n // document.body.classList.toggle(RIGHT_COLUMN_ACTIVE_CLASSNAME, id === 2);\n\n return animationPromise;\n }\n\n public updateStatus() {\n return this.managers.appUsersManager.updateMyOnlineStatus(this.offline);\n }\n\n private createNewChat() {\n const chat = new Chat(\n this,\n this.managers\n );\n\n if(this.chats.length) {\n chat.setBackground(this.lastBackgroundUrl, true);\n }\n\n this.chats.push(chat);\n\n return chat;\n }\n\n private spliceChats(fromIndex: number, justReturn = true, animate?: boolean, spliced?: Chat[]) {\n if(fromIndex >= this.chats.length) return;\n\n const chatFrom = this.chat;\n if(this.chats.length > 1 && justReturn) {\n this.dispatchEvent('peer_changing', this.chat);\n }\n\n if(!spliced) {\n spliced = this.chats.splice(fromIndex, this.chats.length - fromIndex);\n }\n\n const chatTo = this.chat;\n this.dispatchEvent('chat_changing', {from: chatFrom, to: chatTo});\n\n // * -1 because one item is being sliced when closing the chat by calling .removeByType\n for(let i = 0; i < spliced.length - 1; ++i) {\n appNavigationController.removeByType('chat', true);\n }\n\n // * fix middle chat z-index on animation\n if(spliced.length > 1) {\n spliced.slice(0, -1).forEach((chat) => {\n chat.container.remove();\n });\n }\n\n this.chatsSelectTab(chatTo.container, animate);\n\n if(justReturn) {\n this.dispatchEvent('peer_changed', chatTo);\n\n const searchTab = appSidebarRight.getTab(AppPrivateSearchTab);\n searchTab?.close();\n\n appSidebarRight.replaceSharedMediaTab(chatTo.sharedMediaTab);\n }\n\n spliced.forEach((chat) => {\n chat.beforeDestroy();\n });\n\n setTimeout(() => {\n // chat.setPeer(0);\n spliced.forEach((chat) => {\n chat.destroy();\n });\n }, 250 + 100);\n }\n\n public async setPeer(options: Partial<ChatSetInnerPeerOptions> = {}, animate?: boolean): Promise<boolean> {\n if(this.init) {\n this.init();\n this.init = null;\n }\n\n options.peerId ??= NULL_PEER_ID;\n\n const {peerId, lastMsgId, threadId} = options;\n\n const chat = this.chat;\n const chatIndex = this.chats.indexOf(chat);\n const isSamePeer = this.isSamePeer(chat, options as any);\n if(!peerId) {\n if(chatIndex > 0) {\n this.spliceChats(chatIndex, undefined, animate);\n return;\n } else if(mediaSizes.activeScreen === ScreenSize.medium) { // * floating sidebar case\n this.selectTab(+!this.tabId, animate);\n return;\n }\n } else if(chatIndex > 0 && chat.peerId && !isSamePeer) {\n // const firstChat = this.chats[0];\n // if(firstChat.peerId !== chat.peerId) {\n /* // * slice idx > 0, set background and slice first, so new one will be the first\n const spliced = this.chats.splice(1, this.chats.length - 1);\n this.createNewChat();\n this.chats.splice(0, 1); */\n const spliced = this.chats.splice(1, this.chats.length - 1);\n if(this.chat.peerId === peerId) {\n this.spliceChats(0, true, true, spliced);\n return;\n } else {\n const ret = this.setPeer(options);\n this.spliceChats(0, false, false, spliced);\n return ret;\n }\n // } else {\n // this.spliceChats(1, false, animate);\n // }\n\n // return ret;\n }\n\n // * don't reset peer if returning\n if(isSamePeer && mediaSizes.activeScreen <= ScreenSize.medium && document.body.classList.contains(LEFT_COLUMN_ACTIVE_CLASSNAME)) {\n this.selectTab(APP_TABS.CHAT, animate);\n return false;\n }\n\n if(peerId || mediaSizes.activeScreen !== ScreenSize.mobile) {\n const result = await chat.setPeer(options as any as Parameters<Chat['setPeer']>[0]);\n\n // * wait for cached render\n const promise = result?.cached ? result.promise : Promise.resolve();\n if(peerId) {\n Promise.all([\n promise,\n chat.setBackgroundPromise\n ]).then(() => {\n // window.requestAnimationFrame(() => {\n setTimeout(() => { // * setTimeout is better here\n setTimeout(() => {\n this.chatsSelectTab(this.chat.container);\n }, 0);\n this.selectTab(APP_TABS.CHAT, animate);\n }, 0);\n });\n }\n }\n\n if(!peerId) {\n this.selectTab(APP_TABS.CHATLIST, animate);\n return false;\n }\n }\n\n public async setInnerPeer(options: ChatSetInnerPeerOptions) {\n const {peerId} = options;\n if(peerId === NULL_PEER_ID || !peerId) {\n return;\n }\n\n if(!options.type) {\n if(options.threadId && !(await this.managers.appPeersManager.isForum(options.peerId))) {\n options.type = 'discussion';\n }\n\n options.type ??= 'chat';\n }\n\n // * reuse current chat\n const existingIndex = this.chats.findIndex((chat) => this.isSamePeer(chat, options) || (mediaSizes.activeScreen === ScreenSize.mobile && this.tabId === 0));\n if(existingIndex !== -1) {\n this.spliceChats(existingIndex + 1);\n return this.setPeer(options);\n }\n\n const oldChat = this.chat;\n let chat = oldChat;\n if(oldChat.inited) { // * use first not inited chat\n chat = this.createNewChat();\n }\n\n this.dispatchEvent('chat_changing', {from: oldChat, to: chat});\n\n // this.chatsSelectTab(chat.container);\n\n return this.setPeer(options);\n }\n\n public openScheduled(peerId: PeerId) {\n this.setInnerPeer({\n peerId,\n type: 'scheduled'\n });\n }\n\n private getTypingElement(action: SendMessageAction) {\n const el = document.createElement('span');\n let c = 'peer-typing';\n el.classList.add(c);\n el.dataset.action = action._;\n switch(action._) {\n case 'sendMessageTypingAction': {\n // default: {\n c += '-text';\n for(let i = 0; i < 3; ++i) {\n const dot = document.createElement('span');\n dot.className = c + '-dot';\n el.append(dot);\n }\n break;\n }\n\n case 'sendMessageUploadAudioAction':\n case 'sendMessageUploadDocumentAction':\n case 'sendMessageUploadRoundAction':\n case 'sendMessageUploadVideoAction':\n case 'sendMessageUploadPhotoAction': {\n c += '-upload';\n /* const trail = document.createElement('span');\n trail.className = c + '-trail';\n el.append(trail); */\n break;\n }\n\n case 'sendMessageRecordAudioAction':\n case 'sendMessageRecordRoundAction':\n case 'sendMessageRecordVideoAction': {\n c += '-record';\n break;\n }\n\n case 'sendMessageEmojiInteractionSeen':\n case 'sendMessageChooseStickerAction': {\n c += '-choosing-sticker';\n for(let i = 0; i < 2; ++i) {\n const eye = document.createElement('div');\n eye.className = c + '-eye';\n el.append(eye);\n }\n break;\n }\n }\n\n el.classList.add(c);\n\n return el;\n }\n\n public async getPeerTyping(peerId: PeerId, container?: HTMLElement, threadId?: number) {\n // const log = this.log.bindPrefix('getPeerTyping-' + peerId);\n // log('getting peer typing');\n\n const isUser = peerId.isUser();\n if(isUser && await this.managers.appUsersManager.isBot(peerId)) {\n // log('a bot');\n return;\n }\n\n const typings = await this.managers.appProfileManager.getPeerTypings(peerId, threadId);\n if(!typings?.length) {\n // log('have no typing');\n return;\n }\n\n const typing = typings[0];\n\n const langPackKeys: {\n [peerType in 'private' | 'chat' | 'multi']?: Partial<{[action in SendMessageAction['_']]: LangPackKey}>\n } = {\n private: {\n 'sendMessageTypingAction': 'Peer.Activity.User.TypingText',\n 'sendMessageUploadAudioAction': 'Peer.Activity.User.SendingFile',\n 'sendMessageUploadDocumentAction': 'Peer.Activity.User.SendingFile',\n 'sendMessageUploadPhotoAction': 'Peer.Activity.User.SendingPhoto',\n 'sendMessageUploadVideoAction': 'Peer.Activity.User.SendingVideo',\n 'sendMessageUploadRoundAction': 'Peer.Activity.User.SendingVideo',\n 'sendMessageRecordVideoAction': 'Peer.Activity.User.RecordingVideo',\n 'sendMessageRecordAudioAction': 'Peer.Activity.User.RecordingAudio',\n 'sendMessageRecordRoundAction': 'Peer.Activity.User.RecordingVideo',\n 'sendMessageGamePlayAction': 'Peer.Activity.User.PlayingGame',\n 'sendMessageChooseStickerAction': 'Peer.Activity.User.ChoosingSticker',\n 'sendMessageEmojiInteractionSeen': 'Peer.Activity.User.EnjoyingAnimations'\n },\n chat: {\n 'sendMessageTypingAction': 'Peer.Activity.Chat.TypingText',\n 'sendMessageUploadAudioAction': 'Peer.Activity.Chat.SendingFile',\n 'sendMessageUploadDocumentAction': 'Peer.Activity.Chat.SendingFile',\n 'sendMessageUploadPhotoAction': 'Peer.Activity.Chat.SendingPhoto',\n 'sendMessageUploadVideoAction': 'Peer.Activity.Chat.SendingVideo',\n 'sendMessageUploadRoundAction': 'Peer.Activity.Chat.SendingVideo',\n 'sendMessageRecordVideoAction': 'Peer.Activity.Chat.RecordingVideo',\n 'sendMessageRecordAudioAction': 'Peer.Activity.Chat.RecordingAudio',\n 'sendMessageRecordRoundAction': 'Peer.Activity.Chat.RecordingVideo',\n 'sendMessageGamePlayAction': 'Peer.Activity.Chat.PlayingGame',\n 'sendMessageChooseStickerAction': 'Peer.Activity.Chat.ChoosingSticker',\n 'sendMessageEmojiInteractionSeen': 'Peer.Activity.Chat.EnjoyingAnimations'\n },\n multi: {\n 'sendMessageTypingAction': 'Peer.Activity.Chat.Multi.TypingText1',\n 'sendMessageUploadAudioAction': 'Peer.Activity.Chat.Multi.SendingFile1',\n 'sendMessageUploadDocumentAction': 'Peer.Activity.Chat.Multi.SendingFile1',\n 'sendMessageUploadPhotoAction': 'Peer.Activity.Chat.Multi.SendingPhoto1',\n 'sendMessageUploadVideoAction': 'Peer.Activity.Chat.Multi.SendingVideo1',\n 'sendMessageUploadRoundAction': 'Peer.Activity.Chat.Multi.SendingVideo1',\n 'sendMessageRecordVideoAction': 'Peer.Activity.Chat.Multi.RecordingVideo1',\n 'sendMessageRecordAudioAction': 'Peer.Activity.Chat.Multi.RecordingAudio1',\n 'sendMessageRecordRoundAction': 'Peer.Activity.Chat.Multi.RecordingVideo1',\n 'sendMessageGamePlayAction': 'Peer.Activity.Chat.Multi.PlayingGame1',\n 'sendMessageChooseStickerAction': 'Peer.Activity.Chat.Multi.ChoosingSticker1'\n }\n };\n\n const mapa = isUser ? langPackKeys.private : (typings.length > 1 ? langPackKeys.multi : langPackKeys.chat);\n let action = typing.action;\n\n if(typings.length > 1) {\n const s: any = {};\n typings.forEach((typing) => {\n const type = typing.action._;\n if(s[type] === undefined) s[type] = 0;\n ++s[type];\n });\n\n if(Object.keys(s).length > 1) {\n action = {\n _: 'sendMessageTypingAction'\n };\n }\n }\n\n const langPackKey = mapa[action._];\n if(!langPackKey) {\n // log('no langPackKey');\n return;\n }\n\n let peerTitlePromise: Promise<any>;\n let args: any[];\n if(peerId.isAnyChat()) {\n const peerTitle = new PeerTitle();\n peerTitlePromise = peerTitle.update({peerId: typing.userId.toPeerId(false), onlyFirstName: true});\n args = [\n peerTitle.element,\n typings.length - 1\n ];\n\n await peerTitlePromise;\n }\n\n if(!container) {\n container = document.createElement('span');\n container.classList.add('online', 'peer-typing-container');\n }\n\n container.classList.toggle('peer-typing-flex', action._ === 'sendMessageChooseStickerAction' || action._ === 'sendMessageEmojiInteractionSeen');\n\n let typingElement = container.firstElementChild as HTMLElement;\n if(!typingElement) {\n typingElement = this.getTypingElement(action);\n container.prepend(typingElement);\n } else {\n if(typingElement.dataset.action !== action._) {\n typingElement.replaceWith(this.getTypingElement(action));\n }\n }\n\n if(action._ === 'sendMessageEmojiInteractionSeen') {\n if(args) {\n args.pop();\n } else {\n args = [];\n }\n\n const span = htmlToSpan(wrapEmojiText(action.emoticon));\n args.push(span);\n }\n\n const descriptionElement = i18n(langPackKey, args);\n descriptionElement.classList.add('peer-typing-description');\n\n if(container.childElementCount > 1) container.lastElementChild.replaceWith(descriptionElement);\n else container.append(descriptionElement);\n\n // log('returning typing');\n return container;\n }\n\n private async getChatStatus(chatId: ChatId, noTyping?: boolean): Promise<AckedResult<HTMLElement>> {\n const typingEl = noTyping ? undefined : await this.getPeerTyping(chatId.toPeerId(true));\n if(typingEl) {\n return {cached: true, result: Promise.resolve(typingEl)};\n }\n\n const result = await this.managers.acknowledged.appProfileManager.getChatFull(chatId);\n const dooo = async(chatInfo: ChatFull) => {\n // this.chat.log('chatInfo res:', chatInfo);\n\n const participants_count = (chatInfo as ChatFull.channelFull).participants_count ||\n ((chatInfo as ChatFull.chatFull).participants as ChatParticipants.chatParticipants)?.participants?.length ||\n 1;\n // if(participants_count) {\n let subtitle = await getChatMembersString(chatId);\n\n if(participants_count < 2) {\n return subtitle;\n }\n\n const onlines = await this.managers.appProfileManager.getOnlines(chatId);\n if(onlines > 1) {\n const span = document.createElement('span');\n\n span.append(...join([subtitle, i18n('OnlineCount', [numberThousandSplitter(onlines)])], false));\n subtitle = span;\n }\n\n return subtitle;\n // }\n };\n\n const promise = Promise.resolve(result.result).then(dooo);\n return {\n cached: result.cached,\n result: promise\n };\n }\n\n private async getUserStatus(userId: UserId, ignoreSelf?: boolean) {\n const result: AckedResult<HTMLElement> = {\n cached: true,\n result: Promise.resolve(undefined as HTMLElement)\n };\n\n const user = await this.managers.appUsersManager.getUser(userId);\n if(!user || (user.pFlags.self && !ignoreSelf)) {\n return result;\n }\n\n const subtitle = getUserStatusString(user);\n\n if(!user.pFlags.bot && !user.pFlags.support) {\n let typingEl = await this.getPeerTyping(userId.toPeerId());\n if(!typingEl && user.status?._ === 'userStatusOnline') {\n typingEl = document.createElement('span');\n typingEl.classList.add('online');\n typingEl.append(subtitle);\n }\n\n if(typingEl) {\n result.result = Promise.resolve(typingEl);\n return result;\n }\n }\n\n result.result = Promise.resolve(subtitle);\n return result;\n }\n\n private async getPeerStatus(peerId: PeerId, ignoreSelf?: boolean, noTyping?: boolean) {\n if(!peerId) return;\n let promise: Promise<AckedResult<HTMLElement>>;\n if(peerId.isAnyChat()) {\n promise = this.getChatStatus(peerId.toChatId(), noTyping);\n } else {\n promise = this.getUserStatus(peerId.toUserId(), ignoreSelf);\n }\n\n return promise;\n }\n\n public async setPeerStatus(options: {\n peerId: PeerId,\n element: HTMLElement,\n needClear: boolean,\n useWhitespace: boolean,\n middleware: () => boolean,\n ignoreSelf?: boolean,\n noTyping?: boolean\n }) {\n // const log = this.log.bindPrefix('status-' + peerId);\n // log('setting status', element);\n\n const {peerId, element, needClear, useWhitespace, middleware, ignoreSelf, noTyping} = options;\n\n if(!needClear) {\n // * good good good\n const typingContainer = element.querySelector('.peer-typing-container') as HTMLElement;\n if(typingContainer && await this.getPeerTyping(peerId, typingContainer)) {\n // log('already have a status');\n return;\n }\n }\n\n const result = await this.getPeerStatus(peerId, ignoreSelf, noTyping);\n // log('getPeerStatus result', result);\n if(!middleware()) {\n // log.warn('middleware');\n return;\n }\n\n const set = async() => {\n const subtitle = result && await result.result;\n if(!middleware()) {\n return;\n }\n\n return () => replaceContent(element, subtitle || placeholder);\n };\n\n const placeholder = useWhitespace ? NBSP : ''; // ! HERE U CAN FIND WHITESPACE\n if(!result || result.cached || needClear === undefined) {\n return await set();\n } else if(needClear) {\n return () => {\n element.textContent = placeholder;\n return set().then((callback) => callback?.());\n };\n }\n }\n\n public setChoosingStickerTyping(cancel: boolean) {\n this.managers.appMessagesManager.setTyping(this.chat.peerId, {_: cancel ? 'sendMessageCancelAction' : 'sendMessageChooseStickerAction'}, undefined, this.chat.threadId);\n }\n\n public isSamePeer(options1: {peerId: PeerId, threadId?: number, type?: ChatType}, options2: typeof options1) {\n return options1.peerId === options2.peerId &&\n options1.threadId === options2.threadId &&\n (typeof(options1.type) !== typeof(options2.type) || options1.type === options2.type);\n }\n\n public giftPremium(peerId: PeerId) {\n this.managers.appProfileManager.getProfile(peerId.toUserId()).then((profile) => {\n PopupElement.createPopup(PopupGiftPremium, peerId, profile.premium_gifts);\n });\n }\n}\n\nconst appImManager = new AppImManager();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.appImManager = appImManager);\nexport default appImManager;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport enum INTERNAL_LINK_TYPE {\n MESSAGE,\n PRIVATE_POST,\n STICKER_SET,\n JOIN_CHAT,\n VOICE_CHAT,\n USER_PHONE_NUMBER,\n INVOICE,\n EMOJI_SET,\n ATTACH_MENU_BOT\n};\n\nexport type InternalLink = InternalLink.InternalLinkMessage | InternalLink.InternalLinkPrivatePost | InternalLink.InternalLinkStickerSet | InternalLink.InternalLinkJoinChat | InternalLink.InternalLinkVoiceChat | InternalLink.InternalLinkUserPhoneNumber | InternalLink.InternalLinkInvoice | InternalLink.InternalLinkEmojiSet | InternalLink.InternalLinkAttachMenuBot;\n\nexport namespace InternalLink {\n export interface InternalLinkMessage {\n _: INTERNAL_LINK_TYPE.MESSAGE,\n domain: string,\n post?: string,\n comment?: string,\n thread?: string,\n start?: string,\n t?: string, // media timestamp\n stack?: number // local\n }\n\n export interface InternalLinkPrivatePost {\n _: INTERNAL_LINK_TYPE.PRIVATE_POST,\n channel: string,\n post: string,\n thread?: string,\n comment?: string,\n t?: string // media timestamp\n stack?: number // local\n }\n\n export interface InternalLinkStickerSet {\n _: INTERNAL_LINK_TYPE.STICKER_SET,\n set: string\n }\n\n export interface InternalLinkJoinChat {\n _: INTERNAL_LINK_TYPE.JOIN_CHAT,\n invite: string\n }\n\n /**\n * LOCAL LINK\n */\n export interface InternalLinkVoiceChat {\n _: INTERNAL_LINK_TYPE.VOICE_CHAT,\n id: string,\n access_hash: string,\n chat_id: string\n }\n\n export interface InternalLinkUserPhoneNumber {\n _: INTERNAL_LINK_TYPE.USER_PHONE_NUMBER,\n phone: string\n }\n\n export interface InternalLinkInvoice {\n _: INTERNAL_LINK_TYPE.INVOICE,\n slug: string\n }\n\n export interface InternalLinkEmojiSet {\n _: INTERNAL_LINK_TYPE.EMOJI_SET,\n set: string\n }\n\n export interface InternalLinkAttachMenuBot {\n _: INTERNAL_LINK_TYPE.ATTACH_MENU_BOT,\n startattach?: string,\n choose?: string,\n attach?: string,\n domain?: string,\n nestedLink?: InternalLink\n }\n}\n\nexport type InternalLinkTypeMap = {\n [INTERNAL_LINK_TYPE.MESSAGE]: InternalLink.InternalLinkMessage,\n [INTERNAL_LINK_TYPE.PRIVATE_POST]: InternalLink.InternalLinkPrivatePost,\n [INTERNAL_LINK_TYPE.STICKER_SET]: InternalLink.InternalLinkStickerSet,\n [INTERNAL_LINK_TYPE.JOIN_CHAT]: InternalLink.InternalLinkJoinChat,\n [INTERNAL_LINK_TYPE.VOICE_CHAT]: InternalLink.InternalLinkVoiceChat,\n [INTERNAL_LINK_TYPE.USER_PHONE_NUMBER]: InternalLink.InternalLinkUserPhoneNumber,\n [INTERNAL_LINK_TYPE.INVOICE]: InternalLink.InternalLinkInvoice,\n [INTERNAL_LINK_TYPE.EMOJI_SET]: InternalLink.InternalLinkEmojiSet,\n [INTERNAL_LINK_TYPE.ATTACH_MENU_BOT]: InternalLink.InternalLinkAttachMenuBot\n};\n","import {ChannelParticipant, ChatParticipant} from '../../../../layer';\n\nexport default function getParticipantRank(participant: ChannelParticipant | ChatParticipant) {\n return (participant as ChannelParticipant.channelParticipantAdmin).rank ||\n (participant._ === 'channelParticipantAdmin' || participant._ === 'chatParticipantAdmin' ? 2 :\n (participant._ === 'chatParticipantCreator' || participant._ === 'channelParticipantCreator' ? 1 : undefined));\n}\n","import {Message, MessageMedia} from '../../../../layer';\n\nexport default function canSaveMessageMedia(message: Message.message | Message.messageService) {\n return message &&\n !message.pFlags.is_outgoing &&\n !(message as Message.message).pFlags.noforwards &&\n !((message as Message.message).media as MessageMedia.messageMediaInvoice)?.extended_media\n}\n","import {Document, Game, Message, MessageAction, MessageExtendedMedia, MessageMedia, Photo, WebPage} from '../../../../layer';\n\nexport default function getMediaFromMessage(message: Message, onlyInner: true): Photo.photo | Document.document;\nexport default function getMediaFromMessage(message: Message, onlyInner?: false): Photo.photo | Document.document | Game.game | WebPage.webPage;\nexport default function getMediaFromMessage(message: Message, onlyInner = false): Photo.photo | Document.document | Game.game | WebPage.webPage {\n if(!message) return;\n\n let media: any;\n if((message as Message.messageService).action) {\n media = ((message as Message.messageService).action as MessageAction.messageActionChannelEditPhoto).photo;\n } else if((message as Message.message).media) {\n let messageMedia = (message as Message.message).media;\n if((messageMedia as MessageMedia.messageMediaWebPage).webpage) {\n messageMedia = (messageMedia as MessageMedia.messageMediaWebPage).webpage as any as MessageMedia;\n } else if((messageMedia as MessageMedia.messageMediaInvoice).extended_media?._ === 'messageExtendedMedia') {\n messageMedia = ((messageMedia as MessageMedia.messageMediaInvoice).extended_media as MessageExtendedMedia.messageExtendedMedia).media;\n }\n\n media = (messageMedia as MessageMedia.messageMediaDocument).document ||\n (messageMedia as MessageMedia.messageMediaPhoto).photo ||\n (onlyInner ? undefined : (messageMedia as MessageMedia.messageMediaGame).game || messageMedia);\n }\n\n return media as any;\n}\n","import {Message} from '../../../../layer';\nimport type {MyMessage} from '../../appMessagesManager';\n\nexport default function getMessageSenderPeerIdOrName(message: MyMessage) {\n if(message.fromId) {\n return {\n peerId: message.fromId\n };\n } else {\n return {\n fromName: (message as Message.message).fwd_from?.from_name\n };\n }\n}\n","import {isRestricted} from '../../../../helpers/restrictions';\nimport {Message} from '../../../../layer';\n\nexport default function isMessageRestricted(message: Message.message) {\n return !!(message.restriction_reason && isRestricted(message.restriction_reason));\n}\n","// https://github.com/eelcohn/Telegram-API/wiki/Calculating-color-for-a-Telegram-user-on-IRC\n/*\n HTML-color IRC-color Description\n #c03d33 4 red\n #4fad2d 3 green\n #d09306 7 yellow\n #168acd 10 blue\n #8544d6 6 purple\n #cd4073 13 pink\n #2996ad 11 sea\n #ce671b 5 orange\n*/\nconst DialogColorsFg = ['#fc5c51', '#0fb297', '#d09306', '#3d72ed', '#895dd5', '#cd4073', '#00c1a6', '#fa790f'];\nconst DialogColors = ['red', 'green', 'yellow', 'blue', 'violet', 'pink', 'cyan', 'orange'];\nconst DialogColorsMap = [0, 7, 4, 1, 6, 3, 5];\n\nexport default function getPeerColorById(peerId: PeerId, pic = true) {\n if(!peerId) return '';\n\n const idx = DialogColorsMap[Math.abs(+peerId) % 7];\n const color = (pic ? DialogColors : DialogColorsFg)[idx];\n return color;\n}\n","import {Chat, User} from '../../../../layer';\n\nexport default function getPeerEditableUsername(peer: User.user | Chat.channel) {\n if(peer.username) {\n return peer.username;\n }\n\n const usernames = peer.usernames;\n const username = usernames?.find((username) => username.pFlags.editable);\n return username?.username;\n}\n","import isObject from '../../../../helpers/object/isObject';\nimport {InputChannel, InputPeer, Peer} from '../../../../layer';\nimport {NULL_PEER_ID} from '../../../mtproto/mtproto_config';\n\nexport default function getPeerId(peerId: {user_id: UserId} | {channel_id: ChatId} | {chat_id: ChatId} | InputPeer | InputChannel | PeerId | string): PeerId {\n if(peerId !== undefined && ((peerId as string).isPeerId ? (peerId as string).isPeerId() : false)) return peerId as PeerId;\n // if(typeof(peerId) === 'string' && /^[uc]/.test(peerId)) return peerId as PeerId;\n // if(typeof(peerId) === 'number') return peerId;\n else if(isObject(peerId)) {\n const userId = (peerId as Peer.peerUser).user_id;\n if(userId !== undefined) {\n return userId.toPeerId(false);\n }\n\n const chatId = (peerId as Peer.peerChannel).channel_id || (peerId as Peer.peerChat).chat_id;\n if(chatId !== undefined) {\n return chatId.toPeerId(true);\n }\n\n return NULL_PEER_ID; // maybe it is an inputPeerSelf\n // } else if(!peerId) return 'u0';\n } else if(!peerId) return NULL_PEER_ID;\n\n const isUser = (peerId as string).charAt(0) === 'u';\n const peerParams = (peerId as string).substr(1).split('_');\n\n return isUser ? peerParams[0].toPeerId() : (peerParams[0] || '').toPeerId(true);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {MyDocument} from '../../appDocsManager';\nimport type {MyPhoto} from '../../appPhotosManager';\nimport type {PhotoSize, VideoSize, WebDocument} from '../../../../layer';\nimport calcImageInBox from '../../../../helpers/calcImageInBox';\nimport {THUMB_TYPE_FULL} from '../../../mtproto/mtproto_config';\n\nexport default function choosePhotoSize(\n photo: MyPhoto | MyDocument | WebDocument,\n boxWidth = 0,\n boxHeight = 0,\n useBytes = false,\n pushDocumentSize = false\n) {\n if(window.devicePixelRatio > 1) {\n boxWidth *= 2;\n boxHeight *= 2;\n }\n\n /*\n s box 100x100\n m box 320x320\n x box 800x800\n y box 1280x1280\n w box 2560x2560\n a crop 160x160\n b crop 320x320\n c crop 640x640\n d crop 1280x1280 */\n\n let sizes: PhotoSize[] = (photo as MyPhoto).sizes || (photo as MyDocument).thumbs as PhotoSize[];\n let bestPhotoSize: typeof sizes[0] = {_: 'photoSizeEmpty', type: THUMB_TYPE_FULL};\n if(pushDocumentSize && sizes && photo._ !== 'photo') {\n sizes = sizes.concat({\n _: 'photoSize',\n w: photo.w,\n h: photo.h,\n size: photo.size,\n type: THUMB_TYPE_FULL\n });\n }\n\n if(sizes?.length) {\n for(let i = 0, length = sizes.length; i < length; ++i) {\n const photoSize = sizes[i];\n if(!('w' in photoSize) && !('h' in photoSize)) continue;\n\n bestPhotoSize = photoSize;\n\n const size = calcImageInBox(photoSize.w, photoSize.h, boxWidth, boxHeight);\n if(size.width >= boxWidth || size.height >= boxHeight) {\n break;\n }\n }\n\n if(useBytes && bestPhotoSize._ === 'photoSizeEmpty' && sizes[0]._ === 'photoStrippedSize') {\n bestPhotoSize = sizes[0];\n }\n }\n\n return bestPhotoSize;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport safeAssign from '../../helpers/object/safeAssign';\nimport {logger} from '../logger';\nimport createDataChannel from './helpers/createDataChannel';\nimport createPeerConnection from './helpers/createPeerConnection';\nimport LocalConferenceDescription from './localConferenceDescription';\nimport StreamManager from './streamManager';\nimport {Ssrc} from './types';\n\nexport type CallConnectionInstanceOptions = {\n streamManager: StreamManager,\n connection?: RTCPeerConnection,\n log?: ReturnType<typeof logger>\n};\n\nexport default abstract class CallConnectionInstanceBase {\n public connection: RTCPeerConnection;\n public streamManager: StreamManager;\n public dataChannel: RTCDataChannel;\n public description: LocalConferenceDescription;\n public sources: {\n audio: Ssrc,\n video?: Ssrc,\n };\n protected negotiating: Promise<void>;\n protected log: ReturnType<typeof logger>;\n\n constructor(options: CallConnectionInstanceOptions) {\n safeAssign(this, options);\n\n if(!this.log) {\n this.log = this.connection?.log || logger('CALL-CONNECTION-BASE');\n }\n\n this.sources = {} as any;\n }\n\n public createPeerConnection(config?: RTCConfiguration) {\n return this.connection || (this.connection = createPeerConnection(config, this.log.bindPrefix('connection')).connection);\n }\n\n public createDataChannel(dict?: RTCDataChannelInit) {\n return this.dataChannel || (this.dataChannel = createDataChannel(this.connection, dict, this.log.bindPrefix('data')));\n }\n\n public createDescription() {\n return this.description || (this.description = new LocalConferenceDescription(this.connection));\n }\n\n public appendStreamToConference() {\n return this.streamManager.appendToConference(this.description);\n }\n\n public closeConnection() {\n const {connection} = this;\n if(!connection) {\n return;\n }\n\n try {\n connection.log('close');\n connection.close();\n } catch(e) {\n this.log.error(e);\n }\n }\n\n public closeConnectionAndStream(stopStream: boolean) {\n this.closeConnection();\n stopStream && this.streamManager.stop();\n }\n\n protected abstract negotiateInternal(): CallConnectionInstanceBase['negotiating'];\n\n public negotiate() {\n const promise = this.negotiating;\n if(promise) {\n return promise;\n }\n\n return this.negotiating = this.negotiateInternal().finally(() => {\n this.negotiating = undefined;\n });\n }\n\n public sendDataChannelData(data: any) {\n if(this.dataChannel.readyState !== 'open') {\n return;\n }\n\n this.dataChannel.send(JSON.stringify(data));\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {Logger, logger} from '../../logger';\n\nexport default function createPeerConnection(config: RTCConfiguration, log?: Logger) {\n if(!log) {\n log = logger('RTCPeerConnection');\n }\n\n log('constructor');\n\n // @ts-ignore\n const connection = new RTCPeerConnection(config);\n connection.addEventListener('track', (event) => {\n log('ontrack', event);\n });\n connection.addEventListener('signalingstatechange', () => {\n log('onsignalingstatechange', connection.signalingState);\n });\n connection.addEventListener('connectionstatechange', () => {\n log('onconnectionstatechange', connection.connectionState);\n });\n connection.addEventListener('negotiationneeded', () => { // * will be fired every time input device changes\n log('onnegotiationneeded', connection.signalingState);\n });\n connection.addEventListener('icecandidate', (event) => {\n log('onicecandidate', event);\n });\n connection.addEventListener('iceconnectionstatechange', () => {\n log('oniceconnectionstatechange', connection.iceConnectionState);\n });\n connection.addEventListener('datachannel', () => {\n log('ondatachannel');\n });\n\n connection.log = log;\n\n return {connection};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {Logger, logger} from '../../logger';\n\nexport default function createDataChannel(connection: RTCPeerConnection, dict?: RTCDataChannelInit, log?: Logger) {\n // return;\n\n if(!log) {\n log = logger('RTCDataChannel');\n }\n\n const channel = connection.createDataChannel('data', dict);\n\n channel.addEventListener('message', (e) => {\n log('onmessage', e);\n });\n channel.addEventListener('open', () => {\n log('onopen');\n });\n channel.addEventListener('close', () => {\n log('onclose');\n });\n\n channel.log = log;\n\n return channel;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport SDP from '../sdp';\nimport {CallSignalingData, P2PVideoCodec} from '../types';\nimport parseMediaSectionInfo from './parseMediaSectionInfo';\n\nexport default function parseSignalingData(sdp: SDP) {\n const info = parseMediaSectionInfo(sdp, sdp.media[0]);\n\n const data: CallSignalingData.initialSetup = {\n '@type': 'InitialSetup',\n 'fingerprints': [info.fingerprint],\n 'ufrag': info.ufrag,\n 'pwd': info.pwd,\n 'audio': undefined,\n 'video': undefined,\n 'screencast': undefined\n };\n\n const convertNumber = (number: number) => '' + number;\n\n for(const section of sdp.media) {\n const mediaType = section.mediaType;\n if(mediaType === 'application' || !section.isSending) {\n continue;\n }\n\n const codec: P2PVideoCodec = data[mediaType === 'video' && data['video'] ? 'screencast' : mediaType] = {} as any;\n const info = parseMediaSectionInfo(sdp, section);\n codec.ssrc = convertNumber(info.source);\n\n if(info.sourceGroups) {\n codec.ssrcGroups = info.sourceGroups.map((sourceGroup) => ({semantics: sourceGroup.semantics, ssrcs: sourceGroup.sources.map(convertNumber)}));\n }\n\n const rtpExtensions: P2PVideoCodec['rtpExtensions'] = codec.rtpExtensions = [];\n section.attributes.get('extmap').forEach((attribute) => {\n rtpExtensions.push({\n id: +attribute.key,\n uri: attribute.value\n });\n });\n\n const payloadTypesMap: Map<number, P2PVideoCodec['payloadTypes'][0]> = new Map();\n\n const getPayloadType = (id: number) => {\n let payloadType = payloadTypesMap.get(id);\n if(!payloadType) {\n payloadTypesMap.set(id, payloadType = {\n id\n } as any);\n }\n\n return payloadType;\n };\n\n section.attributes.get('rtpmap').forEach((attribute) => {\n const id = +attribute.key;\n const payloadType = getPayloadType(id);\n const splitted = attribute.value.split('/');\n const [name, clockrate, channels] = splitted;\n payloadType.name = name;\n payloadType.clockrate = +clockrate;\n payloadType.channels = channels ? +channels : 0;\n });\n\n section.attributes.get('rtcp-fb').forEach((attribute) => {\n const id = +attribute.key;\n const payloadType = getPayloadType(id);\n payloadType.feedbackTypes = attribute.lines.map((line) => {\n const splitted = line.split(' ');\n const [type, subtype] = splitted;\n return {\n type,\n subtype: subtype || ''\n };\n });\n });\n\n section.attributes.get('fmtp').forEach((attribute) => {\n const id = +attribute.key;\n const payloadType = getPayloadType(id);\n const parameters: P2PVideoCodec['payloadTypes'][0]['parameters'] = payloadType.parameters = {};\n const splitted = attribute.value.split(';');\n for(const str of splitted) {\n const [key, value] = str.split('=');\n parameters[key] = value;\n }\n });\n\n codec.payloadTypes = Array.from(payloadTypesMap.values());\n\n /* if(codec.payloadTypes.length > 5) {\n codec.payloadTypes.length = Math.min(codec.payloadTypes.length, 5);\n } */\n }\n\n return data;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport CallConnectionInstanceBase, {CallConnectionInstanceOptions} from './callConnectionInstanceBase';\nimport CallInstance from './callInstance';\nimport parseSignalingData from './helpers/parseSignalingData';\nimport {parseSdp} from './sdp/utils';\n\nexport default class CallConnectionInstance extends CallConnectionInstanceBase {\n private call: CallInstance;\n\n constructor(options: CallConnectionInstanceOptions & {\n call: CallConnectionInstance['call']\n }) {\n super(options);\n }\n\n protected async negotiateInternal() {\n const {connection, call} = this;\n\n if(!connection.localDescription && !connection.remoteDescription && !call.isOutgoing) {\n return;\n }\n\n let descriptionInit: RTCSessionDescriptionInit;\n if(call.offerReceived) {\n call.offerReceived = false;\n\n const answer = descriptionInit = await connection.createAnswer();\n\n this.log('[sdp] local', answer.type, answer.sdp);\n await connection.setLocalDescription(answer);\n\n this.log('[InitialSetup] send 2');\n } else {\n const offer = descriptionInit = await connection.createOffer();\n\n this.log('[sdp] local', offer.sdp);\n await connection.setLocalDescription(offer);\n\n call.offerSent = true;\n\n this.log('[InitialSetup] send 0');\n }\n\n const initialSetup = parseSignalingData(parseSdp(descriptionInit.sdp));\n call.sendCallSignalingData(initialSetup);\n }\n}\n","const subtle = typeof(window) !== 'undefined' && 'crypto' in window ? window.crypto.subtle : self.crypto.subtle;\n\nexport default subtle;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\nimport bufferConcats from '../../../helpers/bytes/bufferConcats';\nimport subtle from '../../crypto/subtle';\nimport sha256 from '../../crypto/utils/sha256';\n\nconst kMaxIncomingPacketSize = 128 * 1024 * 1024;\n\nexport default class P2PEncryptor {\n private type: 'Signaling';\n private counter: number;\n private seqMap: Map<number, number>;\n\n constructor(private isOutgoing: boolean, private p2pKey: Uint8Array) {\n this.type = 'Signaling';\n this.counter = 0;\n this.seqMap = new Map();\n }\n\n private concatSHA256(parts: Uint8Array[]) {\n return sha256(bufferConcats(...parts));\n }\n\n private async encryptPrepared(buffer: Uint8Array) {\n const result = {\n counter: 0, // this.counterFromSeq(this.readSeq(buffer)),\n bytes: new Uint8Array(16 + buffer.length)\n };\n\n const x = (this.isOutgoing ? 0 : 8) + (this.type === 'Signaling' ? 128 : 0);\n const key = this.p2pKey;\n\n const msgKeyLarge = await this.concatSHA256([key.subarray(x + 88, x + 88 + 32), buffer]);\n const msgKey = result.bytes;\n for(let i = 0; i < 16; ++i) {\n msgKey[i] = msgKeyLarge[i + 8];\n }\n\n const aesKeyIv = await this.prepareAesKeyIv(key, msgKey, x);\n\n const bytes = await this.aesProcessCtr(buffer, buffer.length, aesKeyIv, true);\n\n result.bytes = new Uint8Array([...result.bytes.subarray(0, 16), ...bytes]);\n\n return result;\n }\n\n public encryptRawPacket(buffer: Uint8Array) {\n const seq = ++this.counter;\n const arr = new ArrayBuffer(4);\n const view = new DataView(arr);\n view.setUint32(0, seq >>> 0, false); // byteOffset = 0; litteEndian = false\n\n const result = new Uint8Array([...new Uint8Array(arr), ...buffer]);\n\n return this.encryptPrepared(result);\n }\n\n private async prepareAesKeyIv(key: Uint8Array, msgKey: Uint8Array, x: number) {\n const [sha256a, sha256b] = await Promise.all([\n this.concatSHA256([\n msgKey.subarray(0, 16),\n key.subarray(x, x + 36)\n ]),\n\n this.concatSHA256([\n key.subarray(40 + x, 40 + x + 36),\n msgKey.subarray(0, 16)\n ])\n ]);\n\n return {\n key: new Uint8Array([\n ...sha256a.subarray(0, 8),\n ...sha256b.subarray(8, 8 + 16),\n ...sha256a.subarray(24, 24 + 8)\n ]),\n iv: new Uint8Array([\n ...sha256b.subarray(0, 4),\n ...sha256a.subarray(8, 8 + 8),\n ...sha256b.subarray(24, 24 + 4)\n ])\n };\n }\n\n private async aesProcessCtr(encryptedData: Uint8Array, dataSize: number, aesKeyIv: {key: Uint8Array, iv: Uint8Array}, encrypt = true) {\n const cryptoKey = await subtle.importKey(\n 'raw',\n aesKeyIv.key,\n {name: 'AES-CTR'},\n false,\n [encrypt ? 'encrypt' : 'decrypt']\n );\n\n const buffer: ArrayBuffer = await subtle[encrypt ? 'encrypt' : 'decrypt']({\n name: 'AES-CTR',\n counter: aesKeyIv.iv,\n length: aesKeyIv.iv.length * 8\n },\n cryptoKey,\n encryptedData\n );\n\n return new Uint8Array(buffer);\n }\n\n private constTimeIsDifferent(a: Uint8Array, b: Uint8Array, count: number) {\n let msgKeyEquals = true;\n for(let i = 0; i < count; ++i) {\n if(a[i] !== b[i]) {\n msgKeyEquals = false;\n }\n }\n\n return !msgKeyEquals;\n }\n\n public async decryptRawPacket(buffer: Uint8Array) {\n if(buffer.length < 21 || buffer.length > kMaxIncomingPacketSize) {\n return;\n }\n\n const {isOutgoing, type} = this;\n\n const x = (isOutgoing ? 8 : 0) + (type === 'Signaling' ? 128 : 0);\n const key = this.p2pKey;\n\n const msgKey = buffer.subarray(0, 16);\n const encryptedData = buffer.subarray(16);\n const encryptedDataSize = buffer.length - 16;\n\n const aesKeyIv = await this.prepareAesKeyIv(key, msgKey, x);\n\n const decryptionBuffer = await this.aesProcessCtr(encryptedData, encryptedDataSize, aesKeyIv, false);\n\n const msgKeyLarge = await this.concatSHA256([\n key.subarray(88 + x, 88 + x + 32),\n decryptionBuffer\n ]);\n\n if(this.constTimeIsDifferent(msgKeyLarge.subarray(8), msgKey, 16)) {\n return;\n }\n\n const dataView = new DataView(decryptionBuffer.buffer);\n const seq = dataView.getUint32(0);\n if(this.seqMap.has(seq)) {\n return;\n }\n this.seqMap.set(seq, seq);\n\n return decryptionBuffer.slice(4);\n }\n}\n","import convertToUint8Array from '../../../helpers/bytes/convertToUint8Array';\nimport subtle from '../subtle';\n// import sha256 from '@cryptography/sha256';\n\nexport default function sha256(bytes: Parameters<typeof convertToUint8Array>[0]) {\n return subtle.digest('SHA-256', convertToUint8Array(bytes)).then((b) => {\n // console.log('legacy', performance.now() - perfS);\n return new Uint8Array(b);\n });\n /* //console.log('SHA-256 hash start');\n\n let perfS = performance.now();\n\n\n let perfD = performance.now();\n let words = typeof(bytes) === 'string' ? bytes : bytesToWordss(bytes as any);\n let hash = sha256(words);\n console.log('darutkin', performance.now() - perfD);\n\n //console.log('SHA-256 hash finish', hash, sha256(words, 'hex'));\n\n return bytesFromWordss(hash); */\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\nimport StringFromLineBuilder from '../stringFromLineBuilder';\nimport {addDataChannel, addExtmap, addPayloadTypes, addSsrc} from './p2PSdpBuilder';\n\nexport default class ChromeP2PSdpBuilder {\n static generateOffer(info: any) {\n const {fingerprints, ufrag, pwd, audio, video} = info;\n audio.type = 'audio';\n video.type = 'video';\n const media = [audio, video];\n\n const stringBuilder = new StringFromLineBuilder();\n stringBuilder.add(\n 'v=0',\n 'o=- 1 2 IN IP4 127.0.0.1',\n 's=-',\n 't=0 0'\n );\n\n if(fingerprints) {\n fingerprints.forEach((x: any) => {\n const {hash, fingerprint, setup} = x;\n stringBuilder.add(\n `a=fingerprint:${hash} ${fingerprint}`,\n `a=setup:${setup}`\n );\n });\n }\n if(ufrag && pwd) {\n stringBuilder.add(\n `a=ice-ufrag:${ufrag}`,\n `a=ice-pwd:${pwd}`\n );\n }\n\n stringBuilder.add(\n 'a=group:BUNDLE 0 1 2',\n 'a=extmap-allow-mixed',\n 'a=msid-semantic: WMS *'\n );\n const streamName = 'stream' + media.map((x) => x.ssrc).join('_');\n for(let i = 0; i < media.length; i++) {\n const m = media[i];\n const {type, ssrc, ssrcGroups, payloadTypes, rtpExtensions} = m;\n switch(type) {\n case 'audio': {\n stringBuilder.add(\n `m=audio 56930 UDP/TLS/RTP/SAVPF ${payloadTypes.map((x: any) => x.id).join(' ')}`,\n 'c=IN IP4 0.0.0.0',\n 'a=rtcp:9 IN IP4 0.0.0.0',\n 'a=ice-options:trickle',\n `a=mid:${i}`,\n 'a=sendrecv',\n addExtmap(rtpExtensions)\n );\n if(ssrc) {\n stringBuilder.add(`a=msid:${streamName} audio${ssrc}`);\n }\n stringBuilder.add(\n 'a=rtcp-mux',\n addPayloadTypes(payloadTypes),\n addSsrc(type, ssrc, ssrcGroups, streamName)\n );\n\n break;\n }\n\n case 'video': {\n stringBuilder.add(\n `m=video 61986 UDP/TLS/RTP/SAVPF ${payloadTypes.map((x: any) => x.id).join(' ')}`,\n 'c=IN IP4 0.0.0.0',\n 'a=rtcp:9 IN IP4 0.0.0.0',\n 'a=ice-options:trickle',\n `a=mid:${i}`,\n 'a=sendrecv',\n addExtmap(rtpExtensions)\n );\n if(ssrc) {\n stringBuilder.add(`a=msid:${streamName} video${ssrc}`);\n }\n stringBuilder.add(\n 'a=rtcp-mux',\n 'a=rtcp-rsize',\n addPayloadTypes(payloadTypes),\n addSsrc(type, ssrc, ssrcGroups, streamName)\n );\n break;\n }\n }\n }\n stringBuilder.add(addDataChannel(2));\n return stringBuilder.finalize();\n }\n\n static generateAnswer(info: any) {\n const {fingerprints, ufrag, pwd, audio, video} = info;\n audio.type = 'audio';\n video.type = 'video';\n const media = [audio, video];\n\n const stringBuilder = new StringFromLineBuilder();\n stringBuilder.add(\n 'v=0',\n 'o=- 1 2 IN IP4 127.0.0.1',\n 's=-',\n 't=0 0'\n );\n\n if(fingerprints) {\n fingerprints.forEach((x: any) => {\n const {hash, fingerprint, setup} = x;\n stringBuilder.add(\n `a=fingerprint:${hash} ${fingerprint}`,\n `a=setup:${setup}`\n );\n });\n }\n if(ufrag && pwd) {\n stringBuilder.add(\n `a=ice-ufrag:${ufrag}`,\n `a=ice-pwd:${pwd}`\n );\n }\n\n stringBuilder.add(\n 'a=group:BUNDLE 0 1 2',\n 'a=extmap-allow-mixed',\n 'a=msid-semantic: WMS *'\n );\n const streamName = 'stream' + media.map((x) => x.ssrc).join('_');\n for(let i = 0; i < media.length; i++) {\n const m = media[i];\n const {type, ssrc, ssrcGroups, payloadTypes, rtpExtensions} = m;\n switch(type) {\n case 'audio': {\n stringBuilder.add(\n `m=audio 56930 UDP/TLS/RTP/SAVPF ${payloadTypes.map((x: any) => x.id).join(' ')}`,\n 'c=IN IP4 0.0.0.0',\n 'a=rtcp:9 IN IP4 0.0.0.0',\n 'a=ice-options:trickle',\n `a=mid:${i}`,\n 'a=sendrecv',\n addExtmap(rtpExtensions)\n );\n if(ssrc) {\n stringBuilder.add(`a=msid:${streamName} audio${ssrc}`);\n }\n stringBuilder.add(\n 'a=rtcp-mux',\n addPayloadTypes(payloadTypes),\n addSsrc(type, ssrc, ssrcGroups, streamName)\n );\n break;\n }\n\n case 'video': {\n stringBuilder.add(\n `m=video 61986 UDP/TLS/RTP/SAVPF ${payloadTypes.map((x: any) => x.id).join(' ')}`,\n 'c=IN IP4 0.0.0.0',\n 'a=rtcp:9 IN IP4 0.0.0.0',\n 'a=ice-options:trickle',\n `a=mid:${i}`,\n 'a=sendrecv',\n addExtmap(rtpExtensions)\n );\n if(ssrc) {\n stringBuilder.add(`a=msid:${streamName} video${ssrc}`);\n }\n\n stringBuilder.add(\n 'a=rtcp-mux',\n 'a=rtcp-rsize',\n addPayloadTypes(payloadTypes),\n addSsrc(type, ssrc, ssrcGroups, streamName)\n );\n break;\n }\n }\n }\n stringBuilder.add(addDataChannel(2));\n return stringBuilder.finalize();\n }\n}\n","/*\n* Copyright (c) 2018-present, Evgeny Nadymov\n*\n* This source code is licensed under the GPL v.3.0 license found in the\n* LICENSE file in the root directory of this source tree.\n*/\n\nimport ChromeP2PSdpBuilder from './chromeP2PSdpBuilder';\nimport { FirefoxP2PSdpBuilder } from './firefoxP2PSdpBuilder';\nimport { SafariP2PSdpBuilder } from './safariP2PSdpBuilder';\n// import { TG_CALLS_SDP_STRING } from '../../Stores/CallStore';\n\nexport function p2pParseCandidate(candidate) {\n if(!candidate || !candidate.startsWith('candidate:')) {\n return;\n }\n \n const sdpString = candidate;\n candidate = candidate.substr('candidate:'.length);\n \n const [foundation, component, protocol, priority, ip, port, ...other] = candidate.split(' ');\n const c = {\n sdpString,\n foundation,\n component,\n protocol,\n priority,\n address: { ip, port }\n };\n \n for(let i = 0; i < other.length; i += 2) {\n switch(other[i]) {\n case 'typ': {\n c.type = other[i + 1];\n break;\n }\n case 'raddr': {\n if(!c.relAddress) {\n c.relAddress = {};\n }\n \n c.relAddress.ip = other[i + 1];\n break;\n }\n case 'rport': {\n if(!c.relAddress) {\n c.relAddress = {};\n }\n \n c.relAddress.port = other[i + 1];\n break;\n }\n case 'generation': {\n c.generation = other[i + 1];\n break;\n }\n case 'tcptype': {\n c.tcpType = other[i + 1];\n break;\n }\n case 'network-id': {\n c.networkId = other[i + 1];\n break;\n }\n case 'network-cost': {\n c.networkCost = other[i + 1];\n break;\n }\n case 'ufrag': {\n c.username = other[i + 1];\n break;\n }\n }\n }\n \n return c;\n}\n\nexport function p2pParseSdp(sdp) {\n const lines = sdp.split('\\r\\n');\n const lookup = (prefix, force = true, lineFrom = 0, lineTo = Number.MAX_VALUE) => {\n if (lineTo === -1) {\n lineTo = Number.MAX_VALUE;\n }\n for (let i = lineFrom; i < lines.length && i < lineTo; i++) {\n const line = lines[i];\n if (line.startsWith(prefix)) {\n return line.substr(prefix.length);\n }\n }\n \n if (force) {\n console.error(\"Can't find prefix\", prefix);\n }\n \n return null;\n };\n const findIndex = (prefix, lineFrom = 0, lineTo = Number.MAX_VALUE) => {\n if (lineTo === -1) {\n lineTo = Number.MAX_VALUE;\n }\n for (let i = lineFrom; i < lines.length && i < lineTo; i++) {\n const line = lines[i];\n if (line.startsWith(prefix)) {\n return i;\n }\n }\n \n return -1;\n };\n \n const pwdIndex = findIndex('a=ice-pwd:');\n const ufragIndex = findIndex('a=ice-ufrag:');\n if (pwdIndex === -1 && ufragIndex === -1) {\n return {\n // sessionId: lookup('o=').split(' ')[1],\n ufrag: null,\n pwd: null,\n fingerprints: []\n };\n }\n \n const info = {\n // sessionId: lookup('o=').split(' ')[1],\n ufrag: null,\n pwd: null,\n fingerprints: []\n };\n \n let mediaIndex = findIndex('m=');\n const fingerprint = lookup('a=fingerprint:', false);\n const setup = lookup('a=setup:', false);\n if (fingerprint && setup) {\n info.fingerprints.push({\n hash: fingerprint.split(' ')[0],\n fingerprint: fingerprint.split(' ')[1],\n setup\n });\n }\n \n const ufrag = lookup('a=ice-ufrag:', false);\n const pwd = lookup('a=ice-pwd:', false);\n if (ufrag && pwd) {\n info.ufrag = ufrag;\n info.pwd = pwd;\n }\n \n while (mediaIndex !== -1) {\n let nextMediaIndex = findIndex('m=', mediaIndex + 1);\n \n const extmap = [];\n const types = [];\n const mediaType = lookup('m=', true, mediaIndex, nextMediaIndex).split(' ')[0];\n const media = {\n // type: lookup('m=', true, mediaIndex, nextMediaIndex).split(' ')[0],\n // mid: lookup('a=mid:', true, mediaIndex, nextMediaIndex),\n // dir: findDirection(mediaIndex, nextMediaIndex),\n rtpExtensions: extmap,\n payloadTypes: types\n }\n \n const lineTo = nextMediaIndex === -1 ? lines.length : nextMediaIndex;\n const fmtp = new Map();\n const rtcpFb = new Map();\n for (let i = mediaIndex; i < lineTo; i++) {\n const line = lines[i];\n if (line.startsWith('a=extmap:')) {\n const [ id, uri ] = line.substr('a=extmap:'.length).split(' ');\n extmap.push({ id: parseInt(id), uri });\n } else if (line.startsWith('a=fmtp:')) {\n const [ id, str ] = line.substr('a=fmtp:'.length).split(' ');\n const obj = { };\n const arr = str.split(';').map(x => {\n const [ key, value ] = x.split('=');\n obj[key] = value;\n return { [key]: value };\n });\n fmtp.set(parseInt(id), obj);\n } else if (line.startsWith('a=rtcp-fb:')) {\n const [ id, type = '', subtype = '' ] = line.substr('a=rtcp-fb:'.length).split(' ');\n if (rtcpFb.has(parseInt(id))) {\n rtcpFb.get(parseInt(id)).push({ type, subtype });\n } else {\n rtcpFb.set(parseInt(id), [{ type, subtype }])\n }\n } else if (line.startsWith('a=rtpmap')) {\n const [ id, str ] = line.substr('a=rtpmap:'.length).split(' ');\n const [ name, clockrate, channels = '0' ] = str.split('/');\n const obj = { id: parseInt(id), name, clockrate: parseInt(clockrate), channels: parseInt(channels) };\n \n types.push(obj);\n }\n }\n \n for (let i = 0; i < types.length; i++) {\n const { id } = types[i];\n if (rtcpFb.has(id)) {\n types[i].feedbackTypes = rtcpFb.get(id);\n }\n if (fmtp.has(id)) {\n types[i].parameters = fmtp.get(id);\n }\n }\n \n const ssrc = lookup('a=ssrc:', false, mediaIndex, nextMediaIndex);\n if (ssrc) {\n media.ssrc = ssrc.split(' ')[0];\n }\n \n const ssrcGroup = lookup('a=ssrc-group:', false, mediaIndex, nextMediaIndex);\n if (ssrcGroup) {\n const [ semantics, ...ssrcs ] = ssrcGroup.split(' ');\n media.ssrcGroups = [{\n semantics,\n ssrcs\n }]\n }\n \n switch (mediaType) {\n case 'audio': {\n info.audio = media;\n break;\n }\n case 'video': {\n info.video = media;\n break;\n }\n }\n \n mediaIndex = nextMediaIndex;\n }\n\n if(!info.video.ssrcGroups) {\n info.video.ssrcGroups = [];\n }\n\n info['@type'] = 'InitialSetup';\n \n // console.log('[p2pParseSdp]', sdp, info);\n return info;\n}\n\nexport function isFirefox() {\n return navigator.userAgent.toLowerCase().indexOf('firefox') > -1;\n}\n\nfunction isSafari() {\n return navigator.userAgent.toLowerCase().indexOf('safari') > -1 && navigator.userAgent.toLowerCase().indexOf('chrome') === -1;\n}\n\nexport function addExtmap(extmap) {\n let sdp = [];\n // return sdp;\n for (let j = 0; j < extmap.length; j++) {\n const ext = extmap[j];\n const { id, uri } = ext;\n // if (isFirefox() && uri.indexOf(''))\n console.log('[extmap] add', id, uri);\n sdp.push(`a=extmap:${id} ${uri}`);\n }\n \n return sdp.join('\\n');\n}\n\nexport function addPayloadTypes(types) {\n let sdp = [];\n console.log('[SDP] addPayloadTypes', types);\n for (let i = 0; i < types.length; i++) {\n const type = types[i];\n const { id, name, clockrate, channels, feedbackTypes, parameters } = type;\n sdp.push(`a=rtpmap:${id} ${name}/${clockrate}${channels ? '/' + channels : ''}`);\n if (feedbackTypes) {\n feedbackTypes.forEach(x => {\n const { type, subtype } = x;\n sdp.push(`a=rtcp-fb:${id} ${[type, subtype].join(' ')}`);\n });\n }\n if (parameters) {\n const fmtp = [];\n Object.getOwnPropertyNames(parameters).forEach(pName => {\n fmtp.push(`${pName}=${parameters[pName]}`);\n });\n \n sdp.push(`a=fmtp:${id} ${fmtp.join(';')}`);\n }\n }\n \n return sdp.join('\\n');\n}\n\nexport function addSsrc(type, ssrc, ssrcGroups, streamName) {\n let sdp = [];\n \n if (ssrcGroups && ssrcGroups.length > 0) {\n ssrcGroups.forEach(ssrcGroup => {\n if (ssrcGroup && ssrcGroup.ssrcs.length > 0) {\n sdp.push(`a=ssrc-group:${ssrcGroup.semantics} ${ssrcGroup.ssrcs.join(' ')}`);\n ssrcGroup.ssrcs.forEach(ssrc => {\n sdp.push(\n `a=ssrc:${ssrc} cname:stream${ssrc}`,\n `a=ssrc:${ssrc} msid:${streamName} ${type}${ssrc}`,\n `a=ssrc:${ssrc} mslabel:${type}${ssrc}`,\n `a=ssrc:${ssrc} label:${type}${ssrc}`\n );\n });\n }\n });\n } else if (ssrc) {\n sdp.push(\n `a=ssrc:${ssrc} cname:stream${ssrc}`,\n `a=ssrc:${ssrc} msid:${streamName} ${type}${ssrc}`,\n `a=ssrc:${ssrc} mslabel:${type}${ssrc}`,\n `a=ssrc:${ssrc} label:${type}${ssrc}`\n );\n }\n \n return sdp.join('\\n');\n}\n\nexport function addDataChannel(mid) {\n return `m=application 9 UDP/DTLS/SCTP webrtc-datachannel\nc=IN IP4 0.0.0.0\na=ice-options:trickle\na=mid:2\na=sctp-port:5000\na=max-message-size:262144`;\n}\n\nexport class P2PSdpBuilder {\n static generateCandidate(info) {\n if (!info) return null;\n \n const { sdpString, sdpMLineIndex, sdpMid, foundation, component, protocol, priority, address, type, relAddress, generation, tcpType, networkId, networkCost, username } = info;\n if (/* TG_CALLS_SDP_STRING */true) {\n if (sdpString) {\n return {\n candidate: sdpString,\n sdpMLineIndex,\n sdpMid\n };\n }\n }\n throw 'no sdpString';\n \n let candidate = `candidate:${foundation} ${component} ${protocol} ${priority} ${address.ip} ${address.port}`;\n const attrs = []\n if (type) {\n attrs.push(`typ ${type}`);\n }\n if (relAddress) {\n attrs.push(`raddr ${relAddress.ip}`);\n attrs.push(`rport ${relAddress.port}`);\n }\n if (tcpType) {\n attrs.push(`tcptype ${tcpType}`);\n }\n if (generation) {\n attrs.push(`generation ${generation}`);\n }\n if (username) {\n attrs.push(`ufrag ${username}`);\n }\n if (networkId) {\n attrs.push(`network-id ${networkId}`);\n }\n if (networkCost) {\n attrs.push(`network-cost ${networkCost}`);\n }\n if (attrs.length > 0) {\n candidate += ` ${attrs.join(' ')}`;\n }\n \n return { candidate, sdpMid, sdpMLineIndex };\n }\n \n static generateOffer(info) {\n if (isFirefox()) {\n return FirefoxP2PSdpBuilder.generateOffer(info);\n } else if (isSafari()) {\n return SafariP2PSdpBuilder.generateOffer(info);\n }\n \n return ChromeP2PSdpBuilder.generateOffer(info);\n }\n \n static generateAnswer(info) {\n if (isFirefox()) {\n return FirefoxP2PSdpBuilder.generateAnswer(info);\n } else if (isSafari()) {\n return SafariP2PSdpBuilder.generateAnswer(info);\n }\n \n return ChromeP2PSdpBuilder.generateAnswer(info);\n }\n}","/*\n * Copyright (c) 2018-present, Evgeny Nadymov\n *\n * This source code is licensed under the GPL v.3.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { addDataChannel, addExtmap, addPayloadTypes, addSsrc } from './p2PSdpBuilder';\n\nexport class FirefoxP2PSdpBuilder {\n static generateOffer(info) {\n const { fingerprints, ufrag, pwd, audio, video } = info;\n audio.type = 'audio';\n video.type = 'video';\n const media = [audio, video];\n\n let sdp = `v=0\no=- 1 0 IN IP4 0.0.0.0\ns=-\nt=0 0`;\n if (fingerprints) {\n fingerprints.forEach(x => {\n const { hash, fingerprint, setup } = x;\n sdp += `\na=fingerprint:${hash} ${fingerprint}\na=setup:${setup}`;\n });\n }\n if (ufrag && pwd) {\n sdp += `\na=ice-ufrag:${ufrag}\na=ice-pwd:${pwd}`;\n }\n\n sdp += `\na=group:BUNDLE 0 1 2\na=ice-options:trickle\na=msid-semantic:WMS *`;\n const streamName = 'stream' + media.map(x => x.ssrc).join('_');\n for (let i = 0; i < media.length; i++) {\n const m = media[i];\n const { type, ssrc, ssrcGroups, payloadTypes, rtpExtensions } = m;\n switch (type) {\n case 'audio': {\n sdp += `\nm=audio 9 UDP/TLS/RTP/SAVPF ${payloadTypes.map(x => x.id).join(' ')}\nc=IN IP4 0.0.0.0\na=mid:${i}\na=sendrecv`;\n sdp += addExtmap(rtpExtensions);\n sdp += `\na=rtcp-mux`;\n sdp += addPayloadTypes(payloadTypes);\n sdp += addSsrc(type, ssrc, ssrcGroups, streamName);\n\n break;\n }\n case 'video': {\n sdp += `\nm=video 9 UDP/TLS/RTP/SAVPF ${payloadTypes.map(x => x.id).join(' ')}\nc=IN IP4 0.0.0.0\na=mid:${i}\na=sendrecv`;\n sdp += addExtmap(rtpExtensions);\n sdp += `\na=rtcp-mux\na=rtcp-rsize`;\n sdp += addPayloadTypes(payloadTypes);\n sdp += addSsrc(type, ssrc, ssrcGroups, streamName);\n\n break;\n }\n }\n }\n sdp += addDataChannel(2);\n sdp += `\n`;\n\n return sdp;\n }\n\n static generateAnswer(info) {\n const { fingerprints, ufrag, pwd, audio, video } = info;\n audio.type = 'audio';\n video.type = 'video';\n const media = [audio, video];\n\n let sdp = `v=0\no=- 1 0 IN IP4 0.0.0.0\ns=-\nt=0 0`;\n if (fingerprints) {\n fingerprints.forEach(x => {\n const { hash, fingerprint, setup } = x;\n sdp += `\na=fingerprint:${hash} ${fingerprint}\na=setup:${setup}`;\n });\n }\n if (ufrag && pwd) {\n sdp += `\na=ice-ufrag:${ufrag}\na=ice-pwd:${pwd}`;\n }\n\n sdp += `\na=group:BUNDLE 0 1 2\na=ice-options:trickle\na=msid-semantic:WMS *`;\n const streamName = 'stream' + media.map(x => x.ssrc).join('_');\n for (let i = 0; i < media.length; i++) {\n const m = media[i];\n const { type, mid, ssrc, ssrcGroups, payloadTypes, dir, rtpExtensions } = m;\n switch (type) {\n case 'audio': {\n sdp += `\nm=audio 9 UDP/TLS/RTP/SAVPF ${payloadTypes.map(x => x.id).join(' ')}\nc=IN IP4 0.0.0.0\na=mid:${i}\na=sendrecv`;\n sdp += addExtmap(rtpExtensions);\n sdp += `\na=rtcp-mux`;\n sdp += addPayloadTypes(payloadTypes);\n sdp += addSsrc(type, ssrc, ssrcGroups, streamName);\n\n break;\n }\n case 'video': {\n sdp += `\nm=video 9 UDP/TLS/RTP/SAVPF ${payloadTypes.map(x => x.id).join(' ')}\nc=IN IP4 0.0.0.0\na=mid:${i}\na=sendrecv`;\n sdp += addExtmap(rtpExtensions);\n sdp += `\na=rtcp-mux\na=rtcp-rsize`;\n sdp += addPayloadTypes(payloadTypes);\n sdp += addSsrc(type, ssrc, ssrcGroups, streamName);\n break;\n }\n }\n }\n sdp += addDataChannel(2);\n sdp += `\n`;\n\n return sdp;\n }\n}","/*\n * Copyright (c) 2018-present, Evgeny Nadymov\n *\n * This source code is licensed under the GPL v.3.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { addDataChannel, addExtmap, addPayloadTypes, addSsrc } from './p2PSdpBuilder';\n\nexport class SafariP2PSdpBuilder {\n static generateOffer(info) {\n const { fingerprints, ufrag, pwd, audio, video } = info;\n audio.type = 'audio';\n video.type = 'video';\n const media = [audio, video];\n\n if (!media.length) {\n return `v=0\no=- 1 2 IN IP4 127.0.0.1\ns=-\nt=0 0\na=msid-semantic: WMS\n`;\n }\n\n let sdp = `v=0\no=- 1 2 IN IP4 127.0.0.1\ns=-\nt=0 0`;\n if (fingerprints) {\n fingerprints.forEach(x => {\n const { hash, fingerprint, setup } = x;\n sdp += `\na=fingerprint:${hash} ${fingerprint}\na=setup:${setup}`;\n });\n }\n if (ufrag && pwd) {\n sdp += `\na=ice-ufrag:${ufrag}\na=ice-pwd:${pwd}`;\n }\n\n sdp += `\na=group:BUNDLE 0 1 2\na=extmap-allow-mixed\na=msid-semantic: WMS *`;\n const streamName = 'stream' + media.map(x => x.ssrc).join('_');\n for (let i = 0; i < media.length; i++) {\n const m = media[i];\n const { type, ssrc, ssrcGroups, payloadTypes, rtpExtensions } = m;\n switch (type) {\n case 'audio': {\n sdp += `\nm=audio 9 UDP/TLS/RTP/SAVPF ${payloadTypes.map(x => x.id).join(' ')}\nc=IN IP4 0.0.0.0\na=rtcp:9 IN IP4 0.0.0.0\na=ice-options:trickle\na=mid:${i}\na=sendrecv`;\n sdp += addExtmap(rtpExtensions);\n if (ssrc) {\n sdp += `\na=msid:${streamName} audio${ssrc}`;\n }\n sdp += `\na=rtcp-mux`;\n sdp += addPayloadTypes(payloadTypes);\n sdp += addSsrc(type, ssrc, ssrcGroups, streamName);\n\n break;\n }\n case 'video': {\n sdp += `\nm=video 9 UDP/TLS/RTP/SAVPF ${payloadTypes.map(x => x.id).join(' ')}\nc=IN IP4 0.0.0.0\na=rtcp:9 IN IP4 0.0.0.0\na=ice-options:trickle\na=mid:${i}\na=sendrecv`;\n sdp += addExtmap(rtpExtensions);\n if (ssrc) {\n sdp += `\na=msid:${streamName} video${ssrc}`;\n }\n sdp += `\na=rtcp-mux\na=rtcp-rsize`;\n sdp += addPayloadTypes(payloadTypes);\n sdp += addSsrc(type, ssrc, ssrcGroups, streamName);\n break;\n }\n }\n }\n sdp += addDataChannel(2);\n sdp += `\n`;\n\n return sdp;\n }\n\n static generateAnswer(info) {\n const { fingerprints, ufrag, pwd, audio, video } = info;\n audio.type = 'audio';\n video.type = 'video';\n const media = [audio, video];\n\n if (!media.length) {\n return `v=0\no=- 1 2 IN IP4 127.0.0.1\ns=-\nt=0 0\na=msid-semantic: WMS\n`;\n }\n\n let sdp = `v=0\no=- 1 2 IN IP4 127.0.0.1\ns=-\nt=0 0`;\n if (fingerprints) {\n fingerprints.forEach(x => {\n const { hash, fingerprint, setup } = x;\n sdp += `\na=fingerprint:${hash} ${fingerprint}\na=setup:${setup}`;\n });\n }\n if (ufrag && pwd) {\n sdp += `\na=ice-ufrag:${ufrag}\na=ice-pwd:${pwd}`;\n }\n\n sdp += `\na=group:BUNDLE 0 1 2\na=extmap-allow-mixed\na=msid-semantic: WMS *`;\n const streamName = 'stream' + media.map(x => x.ssrc).join('_');\n for (let i = 0; i < media.length; i++) {\n const m = media[i];\n const { type, ssrc, ssrcGroups, payloadTypes, rtpExtensions } = m;\n switch (type) {\n case 'audio': {\n sdp += `\nm=audio 9 UDP/TLS/RTP/SAVPF ${payloadTypes.map(x => x.id).join(' ')}\nc=IN IP4 0.0.0.0\na=rtcp:9 IN IP4 0.0.0.0\na=ice-options:trickle\na=mid:${i}\na=sendrecv`;\n sdp += addExtmap(rtpExtensions);\n if (ssrc) {\n sdp += `\na=msid:${streamName} audio${ssrc}`;\n }\n sdp += `\na=rtcp-mux`;\n sdp += addPayloadTypes(payloadTypes);\n sdp += addSsrc(type, ssrc, ssrcGroups, streamName);\n\n break;\n }\n case 'video': {\n sdp += `\nm=video 9 UDP/TLS/RTP/SAVPF ${payloadTypes.map(x => x.id).join(' ')}\nc=IN IP4 0.0.0.0\na=rtcp:9 IN IP4 0.0.0.0\na=ice-options:trickle\na=mid:${i}\na=sendrecv`;\n sdp += addExtmap(rtpExtensions);\n if (ssrc) {\n sdp += `\na=msid:${streamName} video${ssrc}`;\n }\n sdp += `\na=rtcp-mux\na=rtcp-rsize`;\n sdp += addPayloadTypes(payloadTypes);\n sdp += addSsrc(type, ssrc, ssrcGroups, streamName);\n break;\n }\n }\n }\n sdp += addDataChannel(2);\n sdp += `\n`;\n\n return sdp;\n }\n}","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport ctx from '../../environment/ctx';\nimport {IS_SAFARI} from '../../environment/userAgent';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport debounce from '../../helpers/schedulers/debounce';\nimport {GroupCallParticipantVideoSourceGroup, PhoneCall, PhoneCallDiscardReason, PhoneCallProtocol, Update} from '../../layer';\nimport {emojiFromCodePoints} from '../../vendor/emoji';\nimport type {CallId} from '../appManagers/appCallsManager';\nimport type {AppManagers} from '../appManagers/managers';\nimport {logger} from '../logger';\nimport apiManagerProxy from '../mtproto/mtprotoworker';\nimport CallConnectionInstance from './callConnectionInstance';\nimport CallInstanceBase from './callInstanceBase';\nimport callsController from './callsController';\nimport CALL_STATE from './callState';\nimport {GROUP_CALL_AMPLITUDE_ANALYSE_INTERVAL_MS} from './constants';\nimport parseSignalingData from './helpers/parseSignalingData';\nimport stopTrack from './helpers/stopTrack';\nimport localConferenceDescription, {ConferenceEntry, generateSsrc} from './localConferenceDescription';\nimport getCallProtocol from './p2P/getCallProtocol';\nimport getRtcConfiguration from './p2P/getRtcConfiguration';\nimport P2PEncryptor from './p2P/p2PEncryptor';\nimport {p2pParseCandidate, P2PSdpBuilder} from './p2P/p2PSdpBuilder';\nimport {parseSdp} from './sdp/utils';\nimport {WebRTCLineType} from './sdpBuilder';\nimport StreamManager from './streamManager';\nimport {AudioCodec, CallMediaState, CallSignalingData, DiffieHellmanInfo, P2PAudioCodec, P2PVideoCodec, VideoCodec} from './types';\n\nexport default class CallInstance extends CallInstanceBase<{\n state: (state: CALL_STATE) => void,\n id: (id: CallId, prevId: CallId) => void,\n muted: (muted: boolean) => void,\n mediaState: (mediaState: CallMediaState) => void,\n acceptCallOverride: () => Promise<boolean>,\n}> {\n public dh: Partial<DiffieHellmanInfo.a & DiffieHellmanInfo.b>;\n public id: CallId;\n public call: PhoneCall;\n public interlocutorUserId: UserId;\n public protocol: PhoneCallProtocol;\n public isOutgoing: boolean;\n public encryptionKey: Uint8Array;\n public connectionInstance: CallConnectionInstance;\n public encryptor: P2PEncryptor;\n public decryptor: P2PEncryptor;\n public candidates: RTCIceCandidate[];\n\n public offerReceived: boolean;\n public offerSent: boolean;\n\n public createdParticipantEntries: boolean;\n public release: () => Promise<void>;\n public _connectionState: CALL_STATE;\n\n public createdAt: number;\n public connectedAt: number;\n public discardReason: string;\n\n private managers: AppManagers;\n\n private hangUpTimeout: number;\n\n private mediaStates: {\n input: CallMediaState,\n output?: CallMediaState\n };\n\n private sendMediaState: () => Promise<void>;\n\n private decryptQueue: Uint8Array[];\n\n private getEmojisFingerprintPromise: Promise<CallInstance['emojisFingerprint']>;\n private emojisFingerprint: [string, string, string, string];\n\n private wasStartingScreen: boolean;\n private wasStartingVideo: boolean;\n public wasTryingToJoin: boolean;\n\n public streamManager: StreamManager;\n\n constructor(options: {\n isOutgoing: boolean,\n interlocutorUserId: UserId,\n managers: CallInstance['managers'],\n protocol?: PhoneCallProtocol\n }) {\n super();\n\n this.log = logger('CALL');\n\n if(!this.protocol) {\n this.protocol = getCallProtocol();\n }\n\n safeAssign(this, options);\n\n this.createdAt = Date.now();\n this.offerReceived = false;\n this.offerSent = false;\n this.decryptQueue = [];\n this.candidates = [];\n\n this.addEventListener('state', (state) => {\n this.log('state', CALL_STATE[state]);\n\n if(state === CALL_STATE.CLOSED) {\n this.cleanup();\n }\n });\n\n const streamManager = this.streamManager = new StreamManager(GROUP_CALL_AMPLITUDE_ANALYSE_INTERVAL_MS);\n streamManager.direction = 'sendrecv';\n streamManager.types.push('screencast');\n if(!this.isOutgoing) {\n streamManager.locked = true;\n streamManager.canCreateConferenceEntry = false;\n }\n\n let mediaState: CallMediaState = {\n '@type': 'MediaState',\n 'type': 'input',\n 'lowBattery': false,\n 'muted': true,\n 'screencastState': 'inactive',\n 'videoRotation': 0,\n 'videoState': 'inactive'\n };\n\n const self = this;\n mediaState = new Proxy(mediaState, {\n set: function(target, key, value) {\n // @ts-ignore\n target[key] = value;\n self.setMediaState(mediaState);\n self.sendMediaState();\n return true;\n }\n });\n\n this.mediaStates = {\n input: mediaState\n };\n\n this.sendMediaState = debounce(this._sendMediaState.bind(this), 0, false, true);\n }\n\n get connectionState() {\n const {_connectionState, connectionInstance} = this;\n if(_connectionState !== undefined) {\n return _connectionState;\n } else if(!connectionInstance) {\n return CALL_STATE.CONNECTING;\n } else {\n const {iceConnectionState} = connectionInstance.connection;\n if(iceConnectionState === 'closed') {\n return CALL_STATE.CLOSED;\n } else if(iceConnectionState !== 'connected' && (!IS_SAFARI || iceConnectionState !== 'completed')) {\n return CALL_STATE.CONNECTING;\n } else {\n return CALL_STATE.CONNECTED;\n }\n }\n }\n\n get sortIndex() {\n const connectionState = this.connectionState;\n const state = CALL_STATE.CLOSED - connectionState + 1;\n let index = state * 10000000000000;\n index += 2147483647000 - (connectionState === CALL_STATE.PENDING && this.isOutgoing ? 0 : this.createdAt);\n return index;\n }\n\n public getVideoElement(type: CallMediaState['type']) {\n if(type === 'input') return this.elements.get('main');\n else {\n const mediaState = this.getMediaState('output');\n if(!mediaState) {\n return;\n }\n\n const type: WebRTCLineType = mediaState.videoState === 'active' ? 'video' : (mediaState.screencastState === 'active' ? 'screencast' : undefined);\n if(!type) {\n return;\n }\n\n const entry = this.description.findEntry((entry) => entry.type === type);\n if(!entry) {\n return;\n }\n\n return this.elements.get('' + entry.recvEntry.source);\n }\n }\n\n public async startScreenSharingInternal() {\n try {\n this.wasStartingScreen = true;\n this.wasStartingVideo = false;\n this.streamManager.types = ['audio', 'screencast'];\n await this.requestScreen();\n } catch(err) {\n this.log.error('startScreenSharing error', err);\n }\n }\n\n public async toggleScreenSharing() {\n if(this.isSharingVideo) {\n await this.stopVideoSharing();\n }\n\n if(this.isSharingScreen) {\n return this.stopVideoSharing();\n } else {\n return this.startScreenSharingInternal();\n }\n }\n\n public async startVideoSharingInternal() {\n try {\n this.wasStartingScreen = false;\n this.wasStartingVideo = true;\n this.streamManager.types = ['audio', 'video'];\n await this.requestInputSource(false, true, false);\n } catch(err) {\n this.log.error('startVideoSharing error', err);\n }\n }\n\n public async stopVideoSharing() {\n const mediaState = this.getMediaState('input');\n mediaState.videoState = mediaState.screencastState = 'inactive';\n\n const {streamManager, description} = this;\n const track = streamManager.inputStream.getVideoTracks()[0];\n if(track) {\n stopTrack(track);\n streamManager.appendToConference(description); // clear sender track\n }\n }\n\n public async toggleVideoSharing() {\n if(this.isSharingScreen) {\n await this.stopVideoSharing();\n }\n\n if(this.isSharingVideo) {\n return this.stopVideoSharing();\n } else {\n return this.startVideoSharingInternal();\n }\n }\n\n public getMediaState(type: CallMediaState['type']) {\n return this.mediaStates[type];\n }\n\n public setMediaState(mediaState: CallMediaState) {\n this.mediaStates[mediaState.type] = mediaState;\n this.dispatchEvent('mediaState', mediaState);\n }\n\n public isSharingVideoType(type: 'video' | 'screencast') {\n try {\n const hasVideoTrack = super.isSharingVideo;\n return hasVideoTrack && !!((this.wasStartingScreen && type === 'screencast') || (this.wasStartingVideo && type === 'video'));\n\n // ! it will be used before the track appears\n // return !!this.description.entries.find((entry) => entry.type === type && entry.transceiver.sender.track.enabled);\n } catch(err) {\n return false;\n }\n }\n\n public get isSharingVideo() {\n return this.isSharingVideoType('video');\n }\n\n public get isSharingScreen() {\n return this.isSharingVideoType('screencast');\n }\n\n public get isMuted() {\n const audioTrack = this.streamManager.inputStream.getAudioTracks()[0];\n return !audioTrack?.enabled;\n }\n\n public get isClosing() {\n const {connectionState} = this;\n return connectionState === CALL_STATE.CLOSING || connectionState === CALL_STATE.CLOSED;\n }\n\n public get description(): localConferenceDescription {\n return this.connectionInstance?.description;\n }\n\n public setHangUpTimeout(timeout: number, reason: PhoneCallDiscardReason['_']) {\n this.clearHangUpTimeout();\n this.hangUpTimeout = ctx.setTimeout(() => {\n this.hangUpTimeout = undefined;\n this.hangUp(reason);\n }, timeout);\n }\n\n public clearHangUpTimeout() {\n if(this.hangUpTimeout !== undefined) {\n clearTimeout(this.hangUpTimeout);\n this.hangUpTimeout = undefined;\n }\n }\n\n public setPhoneCall(phoneCall: PhoneCall) {\n this.call = phoneCall;\n\n const {id} = phoneCall;\n if(this.id !== id) {\n const prevId = this.id;\n this.id = id;\n this.dispatchEvent('id', id, prevId);\n }\n }\n\n public async acceptCall() {\n const canAccept = (await Promise.all(this.dispatchResultableEvent('acceptCallOverride')))[0] ?? true;\n if(this.isClosing || !canAccept) {\n return;\n }\n\n // this.clearHangUpTimeout();\n this.overrideConnectionState(CALL_STATE.EXCHANGING_KEYS);\n\n const call = this.call as PhoneCall.phoneCallRequested;\n this.requestInputSource(true, !!call.pFlags.video, false);\n\n const g_a_hash = call.g_a_hash;\n this.managers.appCallsManager.generateDh().then(async(dh) => {\n this.dh = { // ! it is correct\n g_a_hash,\n b: dh.a,\n g_b: dh.g_a,\n g_b_hash: dh.g_a_hash,\n p: dh.p\n };\n\n return this.managers.apiManager.invokeApi('phone.acceptCall', {\n peer: await this.managers.appCallsManager.getCallInput(this.id),\n protocol: this.protocol,\n g_b: this.dh.g_b\n });\n }).then(async(phonePhoneCall) => {\n await this.managers.appCallsManager.savePhonePhoneCall(phonePhoneCall);\n }).catch((err) => {\n this.log.error('accept call error', err);\n // if(err.type === 'CALL_PROTOCOL_COMPAT_LAYER_INVALID') {\n\n // }\n\n this.hangUp('phoneCallDiscardReasonHangup');\n });\n }\n\n public joinCall() {\n this.log('joinCall');\n\n this.getEmojisFingerprint();\n\n this.overrideConnectionState();\n\n const {isOutgoing, encryptionKey, streamManager} = this;\n\n const configuration = getRtcConfiguration(this.call as PhoneCall.phoneCall);\n this.log('joinCall configuration', configuration);\n if(!configuration) return;\n\n const connectionInstance = this.connectionInstance = new CallConnectionInstance({\n call: this,\n streamManager,\n log: this.log.bindPrefix('connection')\n });\n\n const connection = connectionInstance.createPeerConnection(configuration);\n connection.addEventListener('iceconnectionstatechange', () => {\n const state = this.connectionState;\n if(this.connectedAt === undefined && state === CALL_STATE.CONNECTED) {\n this.connectedAt = Date.now();\n }\n\n this.dispatchEvent('state', state);\n });\n connection.addEventListener('negotiationneeded', () => {\n connectionInstance.negotiate();\n });\n connection.addEventListener('icecandidate', (event) => {\n const {candidate} = event;\n connection.log('onicecandidate', candidate);\n if(candidate?.candidate) {\n this.sendIceCandidate(candidate);\n }\n });\n connection.addEventListener('track', (event) => {\n const {track} = event;\n connection.log('ontrack', track);\n this.onTrack(event);\n });\n\n const description = connectionInstance.createDescription();\n\n this.encryptor = new P2PEncryptor(isOutgoing, encryptionKey);\n this.decryptor = new P2PEncryptor(!isOutgoing, encryptionKey);\n\n this.log('currentCall', this);\n\n if(isOutgoing) {\n connectionInstance.appendStreamToConference();\n }\n\n this.createDataChannel();\n\n this.processDecryptQueue();\n }\n\n private createDataChannelEntry() {\n const dataChannelEntry = this.description.createEntry('application');\n dataChannelEntry.setDirection('sendrecv');\n dataChannelEntry.sendEntry = dataChannelEntry.recvEntry = dataChannelEntry;\n }\n\n private createDataChannel() {\n if(this.connectionInstance.dataChannel) {\n return;\n }\n\n const channel = this.connectionInstance.createDataChannel({\n id: 0,\n negotiated: true\n });\n channel.addEventListener('message', (e) => {\n this.applyDataChannelData(JSON.parse(e.data));\n });\n channel.addEventListener('open', () => {\n this.sendMediaState();\n });\n }\n\n private applyDataChannelData(data: CallMediaState) {\n switch(data['@type']) {\n case 'MediaState': {\n data.type = 'output';\n this.log('got output media state', data);\n this.setMediaState(data);\n break;\n }\n\n default:\n this.log.error('unknown data channel data:', data);\n break;\n }\n }\n\n private _sendMediaState() {\n const {connectionInstance} = this;\n if(!connectionInstance) return;\n\n const mediaState = {...this.getMediaState('input')};\n // mediaState.videoRotation = 90;\n delete mediaState.type;\n this.log('sendMediaState', mediaState);\n\n connectionInstance.sendDataChannelData(mediaState);\n }\n\n public async sendCallSignalingData(data: CallSignalingData) {\n /* if(data['@type'] === 'InitialSetup') {\n this.filterNotVP8(data);\n } */\n\n const json = JSON.stringify(data);\n const arr = new TextEncoder().encode(json);\n const {bytes} = await this.encryptor.encryptRawPacket(arr);\n\n this.log('sendCallSignalingData', this.id, json);\n await this.managers.apiManager.invokeApi('phone.sendSignalingData', {\n peer: await this.managers.appCallsManager.getCallInput(this.id),\n data: bytes\n });\n }\n\n public sendIceCandidate(iceCandidate: RTCIceCandidate) {\n this.log('sendIceCandidate', iceCandidate);\n const {candidate, sdpMLineIndex} = iceCandidate;\n if(sdpMLineIndex !== 0) {\n return;\n }\n\n const parsed = p2pParseCandidate(candidate);\n // const parsed = {sdpString: candidate};\n /* if(parsed.address.ip !== '') {\n return;\n } */\n\n this.sendCallSignalingData({\n '@type': 'Candidates',\n 'candidates': [parsed]\n });\n }\n\n public async confirmCall() {\n const {protocol, id, call} = this;\n const dh = this.dh as DiffieHellmanInfo.a;\n\n // this.clearHangUpTimeout();\n this.overrideConnectionState(CALL_STATE.EXCHANGING_KEYS);\n const {key, key_fingerprint} = await this.managers.appCallsManager.computeKey((call as PhoneCall.phoneCallAccepted).g_b, dh.a, dh.p);\n\n const phonePhoneCall = await this.managers.apiManager.invokeApi('phone.confirmCall', {\n peer: await this.managers.appCallsManager.getCallInput(id),\n protocol: protocol,\n g_a: dh.g_a,\n key_fingerprint: key_fingerprint\n });\n\n this.encryptionKey = key;\n await this.managers.appCallsManager.savePhonePhoneCall(phonePhoneCall);\n this.joinCall();\n }\n\n public getEmojisFingerprint() {\n if(this.emojisFingerprint) return this.emojisFingerprint;\n if(this.getEmojisFingerprintPromise) return this.getEmojisFingerprintPromise;\n return this.getEmojisFingerprintPromise = apiManagerProxy.invokeCrypto('get-emojis-fingerprint', this.encryptionKey, this.dh.g_a).then((codePoints) => {\n this.getEmojisFingerprintPromise = undefined;\n return this.emojisFingerprint = codePoints.map((codePoints) => emojiFromCodePoints(codePoints)) as [string, string, string, string];\n });\n }\n\n private unlockStreamManager() {\n this.connectionInstance.streamManager.locked = false;\n this.connectionInstance.appendStreamToConference();\n }\n\n private async doTheMagic() {\n this.connectionInstance.appendStreamToConference();\n\n const connection = this.connectionInstance.connection;\n\n let answer = await connection.createAnswer();\n\n this.log('[sdp] local', answer.type, answer.sdp);\n await connection.setLocalDescription(answer);\n\n connection.getTransceivers().filter((transceiver) => transceiver.direction === 'recvonly').forEach((transceiver) => {\n const entry = this.connectionInstance.description.getEntryByMid(transceiver.mid);\n entry.transceiver = entry.recvEntry.transceiver = transceiver;\n transceiver.direction = 'sendrecv';\n });\n\n const isAnswer = false;\n\n const description = this.description;\n const bundle = description.entries.map((entry) => entry.mid);\n const sdpDescription: RTCSessionDescriptionInit = {\n type: isAnswer ? 'answer' : 'offer',\n sdp: description.generateSdp({\n bundle,\n entries: description.entries.filter((entry) => bundle.includes(entry.mid)),\n // isAnswer: isAnswer\n isAnswer: !isAnswer\n })\n };\n\n await connection.setRemoteDescription(sdpDescription);\n\n answer = await connection.createAnswer();\n\n await connection.setLocalDescription(answer);\n\n const initialSetup = parseSignalingData(parseSdp(answer.sdp));\n this.log('[InitialSetup] send 1');\n this.sendCallSignalingData(initialSetup);\n\n this.unlockStreamManager();\n }\n\n public overrideConnectionState(state?: CALL_STATE) {\n this._connectionState = state;\n this.dispatchEvent('state', this.connectionState);\n }\n\n public get duration() {\n return this.connectedAt !== undefined ? (Date.now() - this.connectedAt) / 1000 | 0 : 0;\n }\n\n protected onInputStream(stream: MediaStream): void {\n super.onInputStream(stream);\n\n const videoTrack = stream.getVideoTracks()[0];\n if(videoTrack) {\n const state = this.getMediaState('input');\n\n // handle starting camera\n if(!this.wasStartingScreen && !this.wasStartingVideo) {\n this.wasStartingVideo = true;\n }\n\n if(this.isSharingVideo) {\n state.videoState = 'active';\n } else if(this.isSharingScreen) {\n state.screencastState = 'active';\n }\n\n videoTrack.addEventListener('ended', () => {\n this.stopVideoSharing();\n }, {once: true});\n }\n\n if(stream.getAudioTracks().length) {\n this.onMutedChange();\n }\n }\n\n private onMutedChange() {\n const isMuted = this.isMuted;\n this.dispatchEvent('muted', isMuted);\n\n const state = this.getMediaState('input');\n state.muted = isMuted;\n }\n\n public toggleMuted(): Promise<void> {\n return this.requestAudioSource(true).then(() => {\n this.setMuted();\n this.onMutedChange();\n });\n }\n\n public async hangUp(discardReason?: PhoneCallDiscardReason['_'], discardedByOtherParty?: boolean) {\n if(this.isClosing) {\n return;\n }\n\n this.discardReason = discardReason;\n this.log('hangUp', discardReason);\n this.overrideConnectionState(CALL_STATE.CLOSED);\n\n if(this.connectionInstance) {\n this.connectionInstance.closeConnectionAndStream(true);\n }\n\n if(discardReason && !discardedByOtherParty) {\n let hasVideo = false;\n for(const type in this.mediaStates) {\n const mediaState = this.mediaStates[type as 'input' | 'output'];\n hasVideo = mediaState.videoState === 'active' || mediaState.screencastState === 'active' || hasVideo;\n }\n\n await this.managers.appCallsManager.discardCall(this.id, this.duration, discardReason, hasVideo);\n }\n }\n\n private performCodec(_codec: P2PAudioCodec | P2PVideoCodec) {\n const payloadTypes: AudioCodec['payload-types'] = _codec.payloadTypes.map((payloadType) => {\n return {\n ...payloadType,\n 'rtcp-fbs': payloadType.feedbackTypes\n }\n });\n\n const codec: AudioCodec = {\n 'rtp-hdrexts': _codec.rtpExtensions,\n 'payload-types': payloadTypes\n };\n\n return codec;\n }\n\n private setDataToDescription(data: CallSignalingData.initialSetup) {\n this.description.setData({\n transport: {\n 'pwd': data.pwd,\n 'ufrag': data.ufrag,\n 'fingerprints': data.fingerprints,\n 'rtcp-mux': true\n },\n audio: this.performCodec(data.audio),\n video: data.video ? this.performCodec(data.video) as VideoCodec : undefined,\n screencast: data.screencast ? this.performCodec(data.screencast) as VideoCodec : undefined\n });\n }\n\n private filterNotVP8(initialSetup: CallSignalingData.initialSetup) {\n if(!this.isOutgoing) { // only VP8 works now\n [initialSetup.video, initialSetup.screencast].filter(Boolean).forEach((codec) => {\n const payloadTypes = codec.payloadTypes;\n const idx = payloadTypes.findIndex((payloadType) => payloadType.name === 'VP8');\n const vp8PayloadType = payloadTypes[idx];\n const rtxIdx = payloadTypes.findIndex((payloadType) => +payloadType.parameters?.apt === vp8PayloadType.id);\n codec.payloadTypes = [payloadTypes[idx], payloadTypes[rtxIdx]];\n });\n }\n }\n\n public async applyCallSignalingData(data: CallSignalingData) {\n this.log('applyCallSignalingData', this, data);\n\n const {connection, description} = this.connectionInstance;\n\n switch(data['@type']) {\n case 'InitialSetup': {\n this.log('[sdp] InitialSetup', data);\n\n this.filterNotVP8(data);\n this.setDataToDescription(data);\n\n const performSsrcGroups = (ssrcGroups: P2PVideoCodec['ssrcGroups']): GroupCallParticipantVideoSourceGroup[] => {\n return ssrcGroups.map((ssrcGroup) => {\n return {\n _: 'groupCallParticipantVideoSourceGroup',\n semantics: ssrcGroup.semantics,\n sources: ssrcGroup.ssrcs.map((source) => +source)\n };\n });\n };\n\n const ssrcs = [\n generateSsrc('audio', +data.audio.ssrc),\n data.video ? generateSsrc('video', performSsrcGroups(data.video.ssrcGroups)) : undefined,\n data.screencast ? generateSsrc('screencast', performSsrcGroups(data.screencast.ssrcGroups)) : undefined\n ].filter(Boolean);\n\n ssrcs.forEach((ssrc) => {\n let entry = description.getEntryBySource(ssrc.source);\n if(entry) {\n return;\n }\n\n const sendRecvEntry = description.findFreeSendRecvEntry(ssrc.type, false);\n entry = new ConferenceEntry(sendRecvEntry.mid, ssrc.type);\n entry.setDirection('sendrecv');\n sendRecvEntry.recvEntry = entry;\n\n description.setEntrySource(entry, ssrc.sourceGroups || ssrc.source);\n });\n\n this.createDataChannelEntry();\n\n const isAnswer = this.offerSent;\n this.offerSent = false;\n\n const bundle = description.entries.map((entry) => entry.mid);\n const sdpDescription: RTCSessionDescriptionInit = {\n type: isAnswer ? 'answer' : 'offer',\n sdp: description.generateSdp({\n bundle,\n entries: description.entries.filter((entry) => bundle.includes(entry.mid)),\n // isAnswer: isAnswer\n isAnswer: !isAnswer\n })\n };\n\n this.log('[sdp] remote', sdpDescription.sdp);\n\n await connection.setRemoteDescription(sdpDescription);\n\n await this.tryToReleaseCandidates();\n\n if(!isAnswer) {\n await this.doTheMagic();\n }\n\n break;\n }\n\n case 'Candidates': {\n for(const candidate of data.candidates) {\n const init: RTCIceCandidateInit = P2PSdpBuilder.generateCandidate(candidate);\n init.sdpMLineIndex = 0;\n const iceCandidate = new RTCIceCandidate(init);\n this.candidates.push(iceCandidate);\n }\n\n await this.tryToReleaseCandidates();\n break;\n }\n\n default: {\n this.log.error('unrecognized signaling data', data);\n }\n }\n }\n\n public async tryToReleaseCandidates() {\n const {connectionInstance} = this;\n if(!connectionInstance) {\n return;\n }\n\n const {connection} = connectionInstance;\n if(connection.remoteDescription) {\n const promises: Promise<void>[] = this.candidates.map((candidate) => this.addIceCandidate(connection, candidate));\n this.candidates.length = 0;\n\n await Promise.all(promises);\n } else {\n this.log('[candidates] postpone');\n }\n }\n\n private async addIceCandidate(connection: RTCPeerConnection, candidate: RTCIceCandidate) {\n this.log('[candidate] start', candidate);\n try {\n // if(!candidate.address) return;\n await connection.addIceCandidate(candidate);\n this.log('[candidate] add', candidate);\n } catch(e) {\n this.log.error('[candidate] error', candidate, e);\n }\n }\n\n private async processDecryptQueue() {\n const {encryptor} = this;\n if(!encryptor) {\n this.log.warn('got encrypted signaling data before the encryption key');\n return;\n }\n\n const length = this.decryptQueue.length;\n if(!length) {\n return;\n }\n\n const queue = this.decryptQueue.slice();\n this.decryptQueue.length = 0;\n\n for(const data of queue) {\n const decryptedData = await encryptor.decryptRawPacket(data);\n if(!decryptedData) {\n continue;\n }\n\n // this.log('[update] updateNewCallSignalingData', update, decryptedData);\n\n const str = new TextDecoder().decode(decryptedData);\n try {\n const signalingData: CallSignalingData = JSON.parse(str);\n this.log('[update] updateNewCallSignalingData', signalingData);\n this.applyCallSignalingData(signalingData);\n } catch(err) {\n this.log.error('wrong signaling data', str);\n this.hangUp('phoneCallDiscardReasonDisconnect');\n callsController.dispatchEvent('incompatible', this.interlocutorUserId);\n }\n }\n }\n\n public onUpdatePhoneCallSignalingData(data: Uint8Array) {\n this.decryptQueue.push(data);\n this.processDecryptQueue();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\nimport {PhoneCallProtocol} from '../../../layer';\n\nexport default function getCallProtocol(): PhoneCallProtocol {\n return {\n _: 'phoneCallProtocol',\n pFlags: {\n udp_p2p: true,\n udp_reflector: true\n },\n min_layer: 92,\n max_layer: 92,\n library_versions: ['4.0.0']\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\nimport {PhoneCall} from '../../../layer';\n\nexport default function getRtcConfiguration(call: PhoneCall.phoneCall): RTCConfiguration {\n const iceServers: RTCIceServer[] = [];\n call.connections.forEach((connection) => {\n switch(connection._) {\n /* case 'callServerTypeTelegramReflector': {\n break;\n } */\n case 'phoneConnectionWebrtc': {\n const {ip, ipv6, port, username, password} = connection;\n const urls: string[] = [];\n if(connection.pFlags.turn) {\n if(ip) {\n urls.push(`turn:${ip}:${port}`);\n }\n if(ipv6) {\n urls.push(`turn:[${ipv6}]:${port}`);\n }\n } else if(connection.pFlags.stun) {\n if(ip) {\n urls.push(`stun:${ip}:${port}`);\n }\n if(ipv6) {\n urls.push(`stun:[${ipv6}]:${port}`);\n }\n }\n\n if(urls.length > 0) {\n iceServers.push({\n urls,\n username,\n credential: password\n });\n }\n break;\n }\n }\n });\n\n return {\n iceServers,\n iceTransportPolicy: call.pFlags.p2p_allowed ? 'all' : 'relay'\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport getScreenStream from './getScreenStream';\nimport getStream from './getStream';\n\n/**\n * ! Use multiple constraints together only with first invoke\n */\nexport default function getStreamCached() {\n const _cache: {\n main: Partial<{\n audio: Promise<MediaStream>,\n video: Promise<MediaStream>\n }>,\n screen: Partial<{\n audio: Promise<MediaStream>,\n video: Promise<MediaStream>\n }>\n } = {\n main: {},\n screen: {}\n };\n\n return async(options: {\n isScreen: true,\n constraints: DisplayMediaStreamOptions,\n } | {\n isScreen?: false,\n constraints: MediaStreamConstraints,\n muted: boolean\n }) => {\n const {isScreen, constraints} = options;\n const cache = _cache[isScreen ? 'screen' : 'main'];\n let promise: Promise<MediaStream> = cache[constraints.audio ? 'audio' : 'video'];\n\n if(!promise) {\n promise = (isScreen ? getScreenStream : getStream)(constraints, (options as any).muted);\n if(constraints.audio && !cache.audio) cache.audio = promise.finally(() => cache.audio = undefined);\n if(constraints.video && !cache.video) cache.video = promise.finally(() => cache.video = undefined);\n }\n\n try {\n return await promise;\n /* let out: Partial<{\n audio: MediaStream,\n video: MediaStream\n }> = {};\n\n await Promise.all([\n constraints.audio && cache.audio.then((stream) => out.audio = stream),\n constraints.video && cache.video.then((stream) => out.video = stream)\n ].filter(Boolean));\n\n return out; */\n } catch(err) {\n throw err;\n }\n };\n}\n\n(window as any).getStreamCached = getStreamCached;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport EventListenerBase, {EventListenerListeners} from '../../helpers/eventListenerBase';\nimport noop from '../../helpers/noop';\nimport {logger} from '../logger';\nimport getAudioConstraints from './helpers/getAudioConstraints';\nimport getScreenConstraints from './helpers/getScreenConstraints';\nimport getStreamCached from './helpers/getStreamCached';\nimport getVideoConstraints from './helpers/getVideoConstraints';\nimport stopTrack from './helpers/stopTrack';\nimport LocalConferenceDescription from './localConferenceDescription';\nimport StreamManager, {StreamItem} from './streamManager';\n\nexport type TryAddTrackOptions = {\n stream: MediaStream,\n track: MediaStreamTrack,\n type: StreamItem['type'],\n source?: string\n};\n\nexport default abstract class CallInstanceBase<E extends EventListenerListeners> extends EventListenerBase<E> {\n protected log: ReturnType<typeof logger>;\n protected outputDeviceId: string;\n\n protected player: HTMLElement;\n protected elements: Map<string, HTMLMediaElement>;\n\n protected audio: HTMLAudioElement;\n // protected fixedSafariAudio: boolean;\n\n protected getStream: ReturnType<typeof getStreamCached>;\n\n constructor() {\n super(false);\n\n const player = this.player = document.createElement('div');\n player.classList.add('call-player');\n player.style.display = 'none';\n document.body.append(player);\n\n this.elements = new Map();\n\n // possible Safari fix\n const audio = this.audio = new Audio();\n audio.autoplay = true;\n audio.volume = 1.0;\n this.player.append(audio);\n this.elements.set('audio', audio);\n\n this.fixSafariAudio();\n\n this.getStream = getStreamCached();\n }\n\n public get isSharingAudio() {\n return !!this.streamManager.hasInputTrackKind('audio');\n }\n\n public get isSharingVideo() {\n return !!this.streamManager.hasInputTrackKind('video');\n }\n\n public abstract get isMuted(): boolean;\n public abstract get isClosing(): boolean;\n\n public fixSafariAudio() {\n // if(this.fixedSafariAudio) return;\n this.audio.play().catch(noop);\n // this.fixedSafariAudio = true;\n }\n\n public requestAudioSource(muted: boolean) {\n return this.requestInputSource(true, false, muted);\n }\n\n public requestInputSource(audio: boolean, video: boolean, muted: boolean) {\n const {streamManager} = this;\n if(streamManager) {\n const isAudioGood = !audio || this.isSharingAudio;\n const isVideoGood = !video || this.isSharingVideo;\n if(isAudioGood && isVideoGood) {\n return Promise.resolve();\n }\n }\n\n const constraints: MediaStreamConstraints = {\n audio: audio && getAudioConstraints(),\n video: video && getVideoConstraints()\n };\n\n return this.getStream({\n constraints,\n muted\n }).then((stream) => {\n this.onInputStream(stream);\n });\n }\n\n public requestScreen() {\n return this.getStream({\n isScreen: true,\n constraints: getScreenConstraints(true)\n }).then((stream) => {\n this.onInputStream(stream);\n });\n }\n\n public getElement(endpoint: number | string) {\n return this.elements.get('' + endpoint);\n }\n\n public abstract get streamManager(): StreamManager;\n public abstract get description(): LocalConferenceDescription;\n public abstract toggleMuted(): Promise<void>;\n\n public cleanup() {\n this.player.textContent = '';\n this.player.remove();\n this.elements.clear();\n\n // can have no connectionInstance but streamManager with input stream\n this.streamManager.stop();\n\n super.cleanup();\n }\n\n public onTrack(event: RTCTrackEvent) {\n this.tryAddTrack({\n stream: event.streams[0],\n track: event.track,\n type: 'output'\n });\n }\n\n public saveInputVideoStream(stream: MediaStream, type?: string) {\n const track = stream.getVideoTracks()[0];\n this.tryAddTrack({\n stream,\n track,\n type: 'input',\n source: type || 'main'\n });\n }\n\n public tryAddTrack({stream, track, type, source}: TryAddTrackOptions) {\n if(!source) {\n source = StreamManager.getSource(stream, type);\n }\n\n this.log('tryAddTrack', stream, track, type, source);\n\n const isOutput = type === 'output';\n\n const {player, elements, streamManager} = this;\n\n const tagName = track.kind as StreamItem['kind'];\n const isVideo = tagName === 'video';\n\n const elementEndpoint = isVideo ? source : tagName;\n let element = elements.get(elementEndpoint);\n\n if(isVideo) {\n track.addEventListener('ended', () => {\n this.log('[track] onended');\n elements.delete(elementEndpoint);\n // element.remove();\n }, {once: true});\n }\n\n if(isOutput) {\n streamManager.addTrack(stream, track, type);\n }\n\n const useStream = isVideo ? stream : streamManager.outputStream;\n if(!element) {\n element = document.createElement(tagName);\n element.autoplay = true;\n element.srcObject = useStream;\n element.volume = 1.0;\n\n if((element as any).sinkId !== 'undefined') {\n const {outputDeviceId} = this;\n if(outputDeviceId) {\n (element as any).setSinkId(outputDeviceId);\n }\n }\n\n if(!isVideo) {\n player.appendChild(element);\n } else {\n element.setAttribute('playsinline', 'true');\n element.muted = true;\n }\n // audio.play();\n\n elements.set(elementEndpoint, element);\n } else {\n if(element.paused) {\n element.play().catch(noop);\n }\n\n // ! EVEN IF MEDIASTREAM IS THE SAME NEW TRACK WON'T PLAY WITHOUT REPLACING IT WHEN NEW PARTICIPANT IS ENTERING !\n // if(element.srcObject !== useStream) {\n element.srcObject = useStream;\n // }\n }\n\n return source;\n }\n\n public setMuted(muted?: boolean) {\n this.streamManager.inputStream.getAudioTracks().forEach((track) => {\n if(track?.kind === 'audio') {\n track.enabled = muted === undefined ? !track.enabled : !muted;\n }\n });\n }\n\n protected onInputStream(stream: MediaStream): void {\n if(!this.isClosing) {\n const videoTracks = stream.getVideoTracks();\n if(videoTracks.length) {\n this.saveInputVideoStream(stream, 'main');\n }\n\n const {streamManager, description} = this;\n streamManager.addStream(stream, 'input');\n\n if(description) {\n streamManager.appendToConference(description);\n }\n } else { // if call is declined earlier than stream appears\n stream.getTracks().forEach((track) => {\n stopTrack(track);\n });\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nenum CALL_STATE {\n CONNECTED,\n CONNECTING,\n EXCHANGING_KEYS,\n PENDING,\n REQUESTING,\n CLOSING,\n CLOSED\n}\n\nexport default CALL_STATE;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport AudioAssetPlayer from '../../helpers/audioAssetPlayer';\n\nexport type CallAudioAssetName = 'call_busy.mp3' | 'call_connect.mp3' | 'call_end.mp3' | 'call_incoming.mp3' | 'call_outgoing.mp3' | 'voip_failed.mp3' | 'voip_connecting.mp3';\n\nlet audioAsset: AudioAssetPlayer<CallAudioAssetName>;\nexport default function getCallAudioAsset() {\n return audioAsset ??= new AudioAssetPlayer([\n 'call_busy.mp3',\n 'call_connect.mp3',\n 'call_end.mp3',\n 'call_incoming.mp3',\n 'call_outgoing.mp3',\n 'voip_failed.mp3'\n ]);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport getCallAudioAsset, {CallAudioAssetName} from '../../components/call/getAudioAsset';\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport IS_CALL_SUPPORTED from '../../environment/callSupport';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport insertInDescendSortedArray from '../../helpers/array/insertInDescendSortedArray';\nimport AudioAssetPlayer from '../../helpers/audioAssetPlayer';\nimport bytesCmp from '../../helpers/bytes/bytesCmp';\nimport EventListenerBase from '../../helpers/eventListenerBase';\nimport tsNow from '../../helpers/tsNow';\nimport {PhoneCallProtocol} from '../../layer';\nimport {CallId} from '../appManagers/appCallsManager';\nimport {AppManagers} from '../appManagers/managers';\nimport {logger} from '../logger';\nimport apiManagerProxy from '../mtproto/mtprotoworker';\nimport {NULL_PEER_ID} from '../mtproto/mtproto_config';\nimport rootScope from '../rootScope';\nimport CallInstance from './callInstance';\nimport CALL_STATE from './callState';\n\nconst CALL_REQUEST_TIMEOUT = 45e3;\n\nexport class CallsController extends EventListenerBase<{\n instance: (details: {hasCurrent: boolean, instance: CallInstance}) => void,\n accepting: (instance: CallInstance) => void, // это костыль. используется при параллельном вызове, чтобы заменить звонок в topbarCall\n incompatible: (userId: UserId) => void,\n}> {\n private log: ReturnType<typeof logger>;\n private managers: AppManagers;\n private audioAsset: AudioAssetPlayer<CallAudioAssetName>;\n private instances: Map<CallId, CallInstance>;\n private sortedInstances: Array<CallInstance>;\n private tempId: number;\n\n public construct(managers: AppManagers) {\n this.managers = managers;\n this.log = logger('CC');\n\n if(!IS_CALL_SUPPORTED) {\n return;\n }\n\n this.audioAsset = getCallAudioAsset();\n this.tempId = 0;\n this.instances = new Map();\n this.sortedInstances = [];\n\n rootScope.addEventListener('call_update', async(call) => {\n let instance = this.instances.get(call.id);\n\n if(instance) {\n instance.setPhoneCall(call);\n }\n\n switch(call._) {\n case 'phoneCallDiscarded': {\n if(instance) {\n instance.hangUp(call.reason?._, true);\n }\n\n break;\n }\n\n case 'phoneCallAccepted': {\n if(instance) {\n /* if(!this.verifyProtocolCompatibility(call.protocol)) {\n instance.hangUp('phoneCallDiscardReasonDisconnect');\n rootScope.dispatchEvent('call_incompatible', instance.interlocutorUserId);\n break;\n } */\n\n instance.confirmCall();\n }\n\n break;\n }\n\n case 'phoneCallRequested': {\n if(!instance) {\n /* if(!this.verifyProtocolCompatibility(call.protocol)) {\n rootScope.dispatchEvent('call_incompatible', call.admin_id);\n break;\n } */\n\n instance = this.createCallInstance({\n isOutgoing: false,\n interlocutorUserId: call.admin_id\n });\n\n instance.overrideConnectionState(CALL_STATE.PENDING);\n instance.setPhoneCall(call);\n instance.setHangUpTimeout(CALL_REQUEST_TIMEOUT, 'phoneCallDiscardReasonMissed');\n }\n\n break;\n }\n\n case 'phoneCall': {\n if(!instance || instance.encryptionKey) {\n break;\n }\n\n const g_a = instance.dh.g_a = call.g_a_or_b;\n const dh = instance.dh;\n const g_a_hash = await apiManagerProxy.invokeCrypto('sha256', g_a);\n if(!bytesCmp(dh.g_a_hash, g_a_hash)) {\n this.log.error('Incorrect g_a_hash', dh.g_a_hash, g_a_hash);\n break;\n }\n\n const {key, key_fingerprint} = await this.managers.appCallsManager.computeKey(g_a, dh.b, dh.p);\n if(call.key_fingerprint !== key_fingerprint) {\n this.log.error('Incorrect key fingerprint', call.key_fingerprint, key_fingerprint, g_a, dh);\n instance.hangUp('phoneCallDiscardReasonDisconnect');\n break;\n }\n\n instance.encryptionKey = key;\n instance.joinCall();\n\n break;\n }\n }\n });\n\n rootScope.addEventListener('call_signaling', ({callId, data}) => {\n const instance = this.instances.get(callId);\n if(instance?.id !== callId) {\n return;\n }\n\n instance.onUpdatePhoneCallSignalingData(data);\n });\n }\n\n public get currentCall() {\n return this.sortedInstances[0];\n }\n\n public getCallByUserId(userId: UserId) {\n for(const [callId, instance] of this.instances) {\n if(instance.interlocutorUserId === userId) {\n return instance;\n }\n }\n }\n\n private createCallInstance(options: {\n isOutgoing: boolean,\n interlocutorUserId: UserId,\n protocol?: PhoneCallProtocol\n }) {\n const call = new CallInstance({\n managers: this.managers,\n ...options\n });\n\n call.addEventListener('state', (state) => {\n const currentCall = this.currentCall;\n if(state === CALL_STATE.CLOSED) {\n this.instances.delete(call.id);\n indexOfAndSplice(this.sortedInstances, call);\n } else {\n insertInDescendSortedArray(this.sortedInstances, call, 'sortIndex');\n }\n\n if(state === CALL_STATE.EXCHANGING_KEYS) {\n call.wasTryingToJoin = true;\n }\n\n const hasConnected = call.connectedAt !== undefined;\n if(state === CALL_STATE.EXCHANGING_KEYS || (state === CALL_STATE.CONNECTING && hasConnected)) {\n call.setHangUpTimeout(CALL_REQUEST_TIMEOUT, 'phoneCallDiscardReasonDisconnect');\n } else {\n call.clearHangUpTimeout();\n }\n\n if(currentCall === call || !currentCall) {\n if(state === CALL_STATE.CLOSED) {\n if(!call.isOutgoing && !call.wasTryingToJoin) { // incoming call has been accepted on other device or ended\n this.audioAsset.stopSound();\n } else if(call.wasTryingToJoin && !hasConnected) { // something has happened during the key exchanging\n this.audioAsset.playSound('voip_failed.mp3');\n } else {\n this.audioAsset.playSound(call.discardReason === 'phoneCallDiscardReasonBusy' ? 'call_busy.mp3' : 'call_end.mp3');\n }\n } else if(state === CALL_STATE.PENDING) {\n this.audioAsset.playSound(call.isOutgoing ? 'call_outgoing.mp3' : 'call_incoming.mp3', true);\n } else if(state === CALL_STATE.EXCHANGING_KEYS) {\n this.audioAsset.playSoundIfDifferent('call_connect.mp3');\n } else if(state === CALL_STATE.CONNECTING) {\n if(call.duration) {\n this.audioAsset.playSound('voip_connecting.mp3', true);\n }\n } else {\n this.audioAsset.stopSound();\n }\n }\n });\n\n call.addEventListener('id', (id, prevId) => {\n if(prevId !== undefined) {\n this.instances.delete(prevId);\n }\n\n const hasCurrent = !!this.currentCall;\n this.instances.set(id, call);\n\n if(prevId === undefined) {\n this.dispatchEvent('instance', {instance: call, hasCurrent: hasCurrent});\n }\n });\n\n return call;\n }\n\n public async startCallInternal(userId: UserId, isVideo: boolean) {\n this.log('p2pStartCallInternal', userId, isVideo);\n\n const fullInfo = await this.managers.appProfileManager.getProfile(userId);\n if(!fullInfo) return;\n\n const {video_calls_available} = fullInfo.pFlags;\n\n const call = this.createCallInstance({\n isOutgoing: true,\n interlocutorUserId: userId\n });\n\n call.requestInputSource(true, !!(isVideo && video_calls_available), false);\n\n call.overrideConnectionState(CALL_STATE.REQUESTING);\n call.setPhoneCall({\n _: 'phoneCallWaiting',\n access_hash: '',\n admin_id: NULL_PEER_ID,\n date: tsNow(true),\n id: --this.tempId,\n participant_id: userId,\n protocol: call.protocol,\n pFlags: {\n video: isVideo || undefined\n }\n });\n\n // return;\n this.managers.appCallsManager.generateDh().then(async(dh) => {\n call.dh = dh;\n\n return this.managers.appCallsManager.requestCall(userId, call.protocol, call.dh.g_a_hash, isVideo && video_calls_available);\n }).then((phoneCall) => {\n call.overrideConnectionState(CALL_STATE.PENDING);\n call.setPhoneCall(phoneCall);\n call.setHangUpTimeout(CALL_REQUEST_TIMEOUT, 'phoneCallDiscardReasonHangup');\n });\n }\n}\n\nconst callsController = new CallsController();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.callsController = callsController);\nexport default callsController;\n","export const GROUP_CALL_AMPLITUDE_ANALYSE_COUNT_MAX = 50;\nexport const GROUP_CALL_AMPLITUDE_ANALYSE_INTERVAL_MS = 100;\nexport const GROUP_CALL_PARTICIPANTS_LOAD_LIMIT = 100;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport forEachReverse from '../../helpers/array/forEachReverse';\nimport throttle from '../../helpers/schedulers/throttle';\nimport {GroupCallConnectionType, JoinGroupCallJsonPayload} from '../appManagers/appGroupCallsManager';\nimport {AppManagers} from '../appManagers/managers';\nimport rootScope from '../rootScope';\nimport CallConnectionInstanceBase, {CallConnectionInstanceOptions} from './callConnectionInstanceBase';\nimport GroupCallInstance from './groupCallInstance';\nimport filterServerCodecs from './helpers/filterServerCodecs';\nimport fixLocalOffer from './helpers/fixLocalOffer';\nimport processMediaSection from './helpers/processMediaSection';\nimport {ConferenceEntry} from './localConferenceDescription';\nimport SDP from './sdp';\nimport SDPMediaSection from './sdp/mediaSection';\nimport {WebRTCLineType} from './sdpBuilder';\nimport {UpdateGroupCallConnectionData} from './types';\n\nexport default class GroupCallConnectionInstance extends CallConnectionInstanceBase {\n private groupCall: GroupCallInstance;\n public updateConstraints?: boolean;\n private type: GroupCallConnectionType;\n private options: {\n type: Extract<GroupCallConnectionType, 'main'>,\n isMuted?: boolean,\n joinVideo?: boolean,\n rejoin?: boolean\n } | {\n type: Extract<GroupCallConnectionType, 'presentation'>,\n };\n\n private updateConstraintsInterval: number;\n public negotiateThrottled: () => void;\n\n private managers: AppManagers;\n\n constructor(options: CallConnectionInstanceOptions & {\n groupCall: GroupCallConnectionInstance['groupCall'],\n type: GroupCallConnectionInstance['type'],\n options: GroupCallConnectionInstance['options'],\n managers: AppManagers\n }) {\n super(options);\n\n this.negotiateThrottled = throttle(this.negotiate.bind(this), 0, false);\n }\n\n public createPeerConnection() {\n return this.connection || super.createPeerConnection({\n iceServers: [],\n iceTransportPolicy: 'all',\n bundlePolicy: 'max-bundle',\n rtcpMuxPolicy: 'require',\n iceCandidatePoolSize: 0\n // sdpSemantics: \"unified-plan\",\n // extmapAllowMixed: true,\n });\n }\n\n public createDataChannel() {\n if(this.dataChannel) {\n return this.dataChannel;\n }\n\n const dataChannel = super.createDataChannel();\n\n dataChannel.addEventListener('open', () => {\n this.maybeUpdateRemoteVideoConstraints();\n });\n\n dataChannel.addEventListener('close', () => {\n if(this.updateConstraintsInterval) {\n clearInterval(this.updateConstraintsInterval);\n this.updateConstraintsInterval = undefined;\n }\n });\n\n return dataChannel;\n }\n\n public createDescription() {\n if(this.description) {\n return this.description;\n }\n\n const description = super.createDescription();\n\n /* const perType = 0;\n const types = ['audio' as const, 'video' as const];\n const count = types.length * perType;\n const init: RTCRtpTransceiverInit = {direction: 'recvonly'};\n types.forEach((type) => {\n for(let i = 0; i < perType; ++i) {\n description.createEntry(type).createTransceiver(connection, init);\n }\n }); */\n\n return description;\n }\n\n public appendStreamToConference() {\n super.appendStreamToConference();/* .then(() => {\n currentGroupCall.connections.main.negotiating = false;\n this.startNegotiation({\n type: type,\n isMuted: muted,\n rejoin\n });\n }); */\n }\n\n private async invokeJoinGroupCall(localSdp: SDP, mainChannels: SDPMediaSection[], options: GroupCallConnectionInstance['options']) {\n const {groupCall, description} = this;\n const groupCallId = groupCall.id;\n\n const processedChannels = mainChannels.map((section) => {\n const processed = processMediaSection(localSdp, section);\n\n this.sources[processed.entry.type as 'video' | 'audio'] = processed.entry;\n\n return processed;\n });\n\n const audioChannel = processedChannels.find((channel) => channel.media.mediaType === 'audio');\n const videoChannel = processedChannels.find((channel) => channel.media.mediaType === 'video');\n let {source, params} = audioChannel || {};\n const useChannel = videoChannel || audioChannel;\n\n const channels: {[type in WebRTCLineType]?: typeof audioChannel} = {\n audio: audioChannel,\n video: videoChannel\n };\n\n description.entries.forEach((entry) => {\n if(entry.direction === 'sendonly') {\n const channel = channels[entry.type];\n if(!channel) return;\n\n description.setEntrySource(entry, channel.sourceGroups || channel.source);\n description.setEntryPeerId(entry, rootScope.myId);\n }\n });\n\n // overwrite ssrc with audio in video params\n if(params !== useChannel.params) {\n const data: JoinGroupCallJsonPayload = JSON.parse(useChannel.params.data);\n // data.ssrc = source || data.ssrc - 1; // audio channel can be missed in screensharing\n if(source) data.ssrc = source;\n else delete data.ssrc;\n params = {\n _: 'dataJSON',\n data: JSON.stringify(data)\n };\n }\n\n const update = await this.managers.appGroupCallsManager.joinGroupCall(groupCallId, params, options);\n\n const data: UpdateGroupCallConnectionData = JSON.parse(update.params.data);\n\n data.audio = data.audio || groupCall.connections.main.description.audio;\n description.setData(data);\n filterServerCodecs(mainChannels, data);\n\n return data;\n }\n\n protected async negotiateInternal() {\n const {connection, description} = this;\n const isNewConnection = connection.iceConnectionState === 'new' && !description.getEntryByMid('0').source;\n const log = this.log.bindPrefix('startNegotiation');\n log('start');\n\n const originalOffer = await connection.createOffer({iceRestart: false});\n\n if(isNewConnection && this.dataChannel) {\n const dataChannelEntry = description.createEntry('application');\n dataChannelEntry.setDirection('sendrecv');\n }\n\n const {sdp: localSdp, offer} = fixLocalOffer({\n offer: originalOffer,\n data: description\n });\n\n log('[sdp] setLocalDescription', offer.sdp);\n await connection.setLocalDescription(offer);\n\n const mainChannels = localSdp.media.filter((media) => {\n return media.mediaType !== 'application' && media.isSending;\n });\n\n if(isNewConnection) {\n try {\n await this.invokeJoinGroupCall(localSdp, mainChannels, this.options);\n } catch(e) {\n this.log.error('[tdweb] joinGroupCall error', e);\n }\n }\n\n /* if(!data) {\n log('abort 0');\n this.closeConnectionAndStream(connection, streamManager);\n return;\n } */\n\n /* if(connection.iceConnectionState !== 'new') {\n log(`abort 1 connectionState=${connection.iceConnectionState}`);\n this.closeConnectionAndStream(connection, streamManager);\n return;\n } */\n /* if(this.currentGroupCall !== currentGroupCall || connectionHandler.connection !== connection) {\n log('abort', this.currentGroupCall, currentGroupCall);\n this.closeConnectionAndStream(connection, streamManager);\n return;\n } */\n\n const isAnswer = true;\n // const _bundleMids = bundleMids.slice();\n const entriesToDelete: ConferenceEntry[] = [];\n const bundle = localSdp.bundle;\n forEachReverse(bundle, (mid, idx, arr) => {\n const entry = description.getEntryByMid(mid);\n if(entry.shouldBeSkipped(isAnswer)) {\n arr.splice(idx, 1);\n entriesToDelete.push(entry);\n }\n });\n\n /* forEachReverse(description.entries, (entry, idx, arr) => {\n const mediaSection = _parsedSdp.media.find((section) => section.oa.get('mid').oa === entry.mid);\n const deleted = !mediaSection;\n // const deleted = !_bundleMids.includes(entry.mid); // ! can't use it because certain mid can be missed in bundle\n if(deleted) {\n arr.splice(idx, 1);\n }\n }); */\n\n const entries = localSdp.media.map((section) => {\n const mid = section.mid;\n let entry = description.getEntryByMid(mid);\n if(!entry) {\n entry = new ConferenceEntry(mid, section.mediaType);\n entry.setDirection('inactive');\n }\n\n return entry;\n });\n\n const answerDescription: RTCSessionDescriptionInit = {\n type: 'answer',\n sdp: description.generateSdp({\n bundle,\n entries,\n isAnswer\n })\n };\n\n entriesToDelete.forEach((entry) => {\n description.deleteEntry(entry);\n });\n\n log(`[sdp] setRemoteDescription signaling=${connection.signalingState} ice=${connection.iceConnectionState} gathering=${connection.iceGatheringState} connection=${connection.connectionState}`, answerDescription.sdp);\n await connection.setRemoteDescription(answerDescription);\n\n log('end');\n }\n\n public negotiate() {\n let promise = this.negotiating;\n if(promise) {\n return promise;\n }\n\n promise = super.negotiate();\n\n if(this.updateConstraints) {\n promise.then(() => {\n this.maybeUpdateRemoteVideoConstraints();\n this.updateConstraints = false;\n });\n }\n\n if(this.options.type === 'presentation') {\n promise.then(() => {\n this.connection.getTransceivers().find((transceiver) => {\n if(transceiver.sender?.track?.kind === 'video') {\n transceiver.sender.setParameters({\n ...transceiver.sender.getParameters(),\n degradationPreference: 'maintain-resolution'\n });\n }\n });\n });\n }\n\n return promise;\n }\n\n public maybeUpdateRemoteVideoConstraints() {\n if(this.dataChannel.readyState !== 'open') {\n return;\n }\n\n this.log('maybeUpdateRemoteVideoConstraints');\n\n // * https://github.com/TelegramMessenger/tgcalls/blob/6f2746e04c9b040f8c8dfc64d916a1853d09c4ce/tgcalls/group/GroupInstanceCustomImpl.cpp#L2549\n type VideoConstraints = {minHeight?: number, maxHeight: number};\n const obj: {\n colibriClass: 'ReceiverVideoConstraints',\n constraints: {[endpoint: string]: VideoConstraints},\n defaultConstraints: VideoConstraints,\n onStageEndpoints: string[]\n } = {\n colibriClass: 'ReceiverVideoConstraints',\n constraints: {},\n defaultConstraints: {maxHeight: 0},\n onStageEndpoints: []\n };\n\n for(const entry of this.description.entries) {\n if(entry.direction !== 'recvonly' || entry.type !== 'video') {\n continue;\n }\n\n const {endpoint} = entry;\n obj.onStageEndpoints.push(endpoint);\n obj.constraints[endpoint] = {\n minHeight: 180,\n maxHeight: 720\n };\n }\n\n this.sendDataChannelData(obj);\n\n if(!obj.onStageEndpoints.length) {\n if(this.updateConstraintsInterval) {\n clearInterval(this.updateConstraintsInterval);\n this.updateConstraintsInterval = undefined;\n }\n } else if(!this.updateConstraintsInterval) {\n this.updateConstraintsInterval = window.setInterval(this.maybeUpdateRemoteVideoConstraints.bind(this), 5000);\n }\n }\n\n public addInputVideoStream(stream: MediaStream) {\n // const {sources} = this;\n // if(sources?.video) {\n // const source = this.sources.video.source;\n // stream.source = '' + source;\n this.groupCall.saveInputVideoStream(stream, this.type);\n // }\n\n this.streamManager.addStream(stream, 'input');\n this.appendStreamToConference(); // replace sender track\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {DataJSON} from '../../../layer';\nimport {JoinGroupCallJsonPayload} from '../../appManagers/appGroupCallsManager';\nimport SDP from '../sdp';\nimport {Ssrc} from '../types';\nimport parseMediaSectionInfo from './parseMediaSectionInfo';\n\nexport default function processMediaSection(sdp: SDP, media: SDP['media'][0]) {\n const sectionInfo = parseMediaSectionInfo(sdp, media);\n\n const mediaType: Exclude<typeof media['mediaType'], 'application'> = media.mediaType as any;\n const entry: Ssrc = {\n source: sectionInfo.source,\n sourceGroups: sectionInfo.sourceGroups,\n type: mediaType\n };\n\n // do not change this value, otherwise onconnectionstatechange won't fire\n sectionInfo.fingerprint.setup = 'active';\n const payload: JoinGroupCallJsonPayload = {\n 'fingerprints': [sectionInfo.fingerprint],\n 'pwd': sectionInfo.pwd,\n 'ssrc': sectionInfo.source,\n 'ssrc-groups': sectionInfo.sourceGroups || [],\n 'ufrag': sectionInfo.ufrag\n };\n const paramsDataJson = JSON.stringify(payload);\n\n const params: DataJSON = {\n _: 'dataJSON',\n data: paramsDataJson\n };\n\n return {\n params,\n source: sectionInfo.source,\n media,\n sourceGroups: sectionInfo.sourceGroups,\n entry\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport forEachReverse from '../../../helpers/array/forEachReverse';\nimport SDPMediaSection from '../sdp/mediaSection';\nimport {UpdateGroupCallConnectionData, Codec} from '../types';\n\nexport default function filterServerCodecs(mainChannels: SDPMediaSection[], data: UpdateGroupCallConnectionData) {\n // ! Need to filter server's extmap for Firefox\n const performExtmap = (channel: typeof mainChannels[0]) => {\n const out: {[id: string]: string} = {};\n const extmap = channel.attributes.get('extmap');\n extmap.forEach((extmap) => {\n const id = extmap.key.split('/', 1)[0];\n out[id] = extmap.value;\n });\n\n return out;\n };\n\n const codecsToPerform: [Codec, 'audio' | 'video'][] = /* flatten([data, dataPresentation].filter(Boolean).map((data) => {\n return */['audio' as const, 'video' as const].filter((type) => data[type]).map((type) => ([data[type], type]));\n // }));\n\n codecsToPerform.forEach(([codec, type]) => {\n const channel = mainChannels.find((line) => line.mediaType === type);\n if(!channel) {\n return;\n }\n\n const extmap = performExtmap(channel);\n forEachReverse(codec['rtp-hdrexts'], (value, index, arr) => {\n if(extmap[value.id] !== value.uri) {\n arr.splice(index, 1);\n console.log(`[sdp] filtered extmap:`, value, index, type);\n }\n });\n });\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport forEachReverse from '../../../helpers/array/forEachReverse';\nimport copy from '../../../helpers/object/copy';\nimport {ConferenceEntry} from '../localConferenceDescription';\nimport {parseSdp, addSimulcast} from '../sdp/utils';\nimport {generateMediaFirstLine, SDPBuilder} from '../sdpBuilder';\nimport {UpdateGroupCallConnectionData} from '../types';\nimport parseMediaSectionInfo from './parseMediaSectionInfo';\n\nexport default function fixLocalOffer(options: {\n offer: RTCSessionDescriptionInit,\n data: UpdateGroupCallConnectionData,\n skipAddingMulticast?: boolean\n // mids?: string[]\n}) {\n const {offer, data} = options;\n const sdp = parseSdp(offer.sdp);\n let hasMunged = false;\n\n if(!options.skipAddingMulticast) {\n hasMunged = addSimulcast(sdp) || hasMunged;\n }\n\n // const bundleLine = parsedSdp.session.lines.find((line) => line.Ha?.key === 'group');\n // const bundleMids = bundleLine.value.split(' ').slice(1);\n\n forEachReverse(sdp.media, (section, idx, arr) => {\n // const mid = section.oa.get('mid').oa;\n\n // это может случиться при выключении и включении видео. почему-то появится секция уже удалённая\n // ! нельзя тут модифицировать локальное описание, будет критовать\n /* if(mids && !mids.includes(mid) && !bundleMids.includes(mid)) {\n console.error('wtf');\n hasMunged = true;\n arr.splice(idx, 1);\n return;\n } */\n\n if(/* section.mediaType !== 'video' || */section.isSending) {\n return;\n }\n\n if(section.mediaType === 'application') {\n return;\n }\n\n const mediaLine = section.mediaLine;\n const mediaLineParts = mediaLine.mediaLineParts;\n const mediaCodecIds = mediaLineParts.ids;\n const localMLine = mediaLine.toString();\n\n const codec = data[section.mediaType];\n const payloadTypes = codec['payload-types'];\n\n /* forEachReverse(payloadTypes, (payloadType, idx, arr) => {\n if(!mediaCodecIds.includes('' + payloadType.id) && section.mediaType === 'video') {\n // if(payloadType.name === 'H265') {\n console.warn('[sdp] filtered unsupported codec', payloadType, mediaCodecIds, section.mediaType);\n arr.splice(idx, 1);\n }\n }); */\n\n const codecIds = payloadTypes.map((payload) => '' + payload.id);\n const correctMLine = generateMediaFirstLine(section.mediaType, undefined, codecIds);\n\n if(localMLine !== correctMLine) {\n const sectionInfo = parseMediaSectionInfo(sdp, section);\n\n const newData = {...data};\n newData.transport = copy(newData.transport);\n newData.transport.ufrag = sectionInfo.ufrag;\n newData.transport.pwd = sectionInfo.pwd;\n newData.transport.fingerprints = [sectionInfo.fingerprint];\n newData.transport.candidates = [];\n\n const entry = new ConferenceEntry(sectionInfo.mid, mediaLineParts.type);\n entry.setPort(mediaLineParts.port);\n sectionInfo.source && entry.setSource(sectionInfo.sourceGroups || sectionInfo.source);\n entry.setDirection(section.direction);\n\n const newSdp = new SDPBuilder().addSsrcEntry(entry, newData).finalize();\n\n const newChannel = parseSdp(newSdp).media[0];\n arr[idx] = newChannel;\n\n hasMunged = true;\n }\n });\n\n if(hasMunged) {\n const mungedSdp = sdp.toString();\n offer.sdp = mungedSdp;\n }\n\n return {offer, sdp/* , bundleMids */};\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {GroupCallConnectionType, GroupCallId, GroupCallOutputSource} from '../appManagers/appGroupCallsManager';\nimport {IS_SAFARI} from '../../environment/userAgent';\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport throttle from '../../helpers/schedulers/throttle';\nimport {GroupCall, GroupCallParticipant} from '../../layer';\nimport {logger} from '../logger';\nimport {NULL_PEER_ID} from '../mtproto/mtproto_config';\nimport rootScope from '../rootScope';\nimport CallInstanceBase, {TryAddTrackOptions} from './callInstanceBase';\nimport GroupCallConnectionInstance from './groupCallConnectionInstance';\nimport GROUP_CALL_STATE from './groupCallState';\nimport getScreenConstraints from './helpers/getScreenConstraints';\nimport getScreenStream from './helpers/getScreenStream';\nimport getStream from './helpers/getStream';\nimport getVideoConstraints from './helpers/getVideoConstraints';\nimport stopTrack from './helpers/stopTrack';\nimport localConferenceDescription from './localConferenceDescription';\nimport {WebRTCLineType} from './sdpBuilder';\nimport StreamManager from './streamManager';\nimport {Ssrc} from './types';\nimport getPeerId from '../appManagers/utils/peers/getPeerId';\nimport {AppManagers} from '../appManagers/managers';\nimport {generateSelfVideo, makeSsrcFromParticipant, makeSsrcsFromParticipant} from './groupCallsController';\n\nexport default class GroupCallInstance extends CallInstanceBase<{\n state: (state: GROUP_CALL_STATE) => void,\n pinned: (source?: GroupCallOutputSource) => void,\n}> {\n public id: GroupCallId;\n public chatId: ChatId;\n public handleUpdateGroupCallParticipants: boolean;\n public updatingSdp: boolean;\n public isSpeakingMap: Map<any, any>;\n public connections: {[k in GroupCallConnectionType]?: GroupCallConnectionInstance};\n public groupCall: GroupCall;\n public participant: GroupCallParticipant;\n\n // will be set with negotiation\n public joined: boolean;\n\n private pinnedSources: Array<GroupCallOutputSource>;\n private participantsSsrcs: Map<PeerId, Ssrc[]>;\n private hadAutoPinnedSources: Set<GroupCallOutputSource>;\n private dispatchPinnedThrottled: () => void;\n private startVideoSharingPromise: Promise<void>;\n private startScreenSharingPromise: Promise<void>;\n\n private managers: AppManagers;\n\n constructor(options: {\n id: GroupCallInstance['id'],\n chatId: GroupCallInstance['chatId'],\n isSpeakingMap?: GroupCallInstance['isSpeakingMap'],\n connections?: GroupCallInstance['connections'],\n managers: AppManagers\n }) {\n super();\n\n safeAssign(this, options);\n\n if(!this.log) {\n this.log = logger('GROUP-CALL');\n }\n\n if(!this.connections) {\n this.connections = {};\n }\n\n if(!this.isSpeakingMap) {\n this.isSpeakingMap = new Map();\n }\n\n this.pinnedSources = [];\n this.participantsSsrcs = new Map();\n this.hadAutoPinnedSources = new Set();\n this.dispatchPinnedThrottled = throttle(() => {\n this.dispatchEvent('pinned', this.pinnedSource);\n }, 0, false);\n\n this.addEventListener('state', (state) => {\n if(state === GROUP_CALL_STATE.CLOSED) {\n this.cleanup();\n }\n });\n }\n\n get connectionState() {\n return this.connections.main.connection.iceConnectionState;\n }\n\n get state() {\n const {connectionState} = this;\n if(connectionState === 'closed') {\n return GROUP_CALL_STATE.CLOSED;\n } else if(connectionState !== 'connected' && (!IS_SAFARI || connectionState !== 'completed')) {\n return GROUP_CALL_STATE.CONNECTING;\n } else {\n const {participant} = this;\n if(!participant.pFlags.can_self_unmute) {\n return GROUP_CALL_STATE.MUTED_BY_ADMIN;\n } else if(participant.pFlags.muted) {\n return GROUP_CALL_STATE.MUTED;\n } else {\n return GROUP_CALL_STATE.UNMUTED;\n }\n }\n }\n\n get participants() {\n return this.managers.appGroupCallsManager.getCachedParticipants(this.id);\n }\n\n get isSharingScreen() {\n return !!this.connections.presentation;\n }\n\n get pinnedSource() {\n return this.pinnedSources[this.pinnedSources.length - 1];\n }\n\n public get isMuted() {\n return this.state !== GROUP_CALL_STATE.UNMUTED;\n }\n\n public get isClosing() {\n const {state} = this;\n return state === GROUP_CALL_STATE.CLOSED;\n }\n\n public get streamManager(): StreamManager {\n return this.connections.main.streamManager;\n }\n\n public get description(): localConferenceDescription {\n return this.connections.main.description;\n }\n\n public pinSource(source: GroupCallOutputSource) {\n indexOfAndSplice(this.pinnedSources, source);\n this.pinnedSources.push(source);\n this.dispatchPinnedThrottled();\n }\n\n public unpinSource(source: GroupCallOutputSource) {\n this.hadAutoPinnedSources.delete(source);\n indexOfAndSplice(this.pinnedSources, source);\n this.dispatchPinnedThrottled();\n }\n\n public unpinAll() {\n this.pinnedSources.length = 0;\n this.dispatchPinnedThrottled();\n }\n\n public async getParticipantByPeerId(peerId: PeerId) {\n return NULL_PEER_ID === peerId ? this.participant : (await this.participants).get(peerId);\n }\n\n public toggleMuted() {\n return this.requestAudioSource(true).then(() => this.changeUserMuted(NULL_PEER_ID));\n }\n\n public async changeUserMuted(peerId: PeerId, muted?: boolean) {\n const participant = await this.getParticipantByPeerId(peerId);\n if(NULL_PEER_ID === peerId && participant.pFlags.can_self_unmute) {\n muted = muted === undefined ? !participant.pFlags.muted : muted;\n }\n\n return this.editParticipant(participant, {muted});\n }\n\n public getElement(endpoint: GroupCallOutputSource) {\n return super.getElement(endpoint);\n }\n\n public getVideoElementFromParticipantByType(participant: GroupCallParticipant, type: 'video' | 'presentation') {\n let source: GroupCallOutputSource;\n if(participant.pFlags.self) {\n const connectionType: GroupCallConnectionType = type === 'video' ? 'main' : 'presentation';\n source = connectionType;\n } else {\n const codec = participant[type];\n source = codec.source_groups[0].sources[0];\n }\n\n const element = this.getElement(source) as HTMLVideoElement;\n if(!element) return;\n\n const clone = element.cloneNode() as typeof element;\n clone.srcObject = element.srcObject;\n return {video: clone, source};\n }\n\n public createConnectionInstance(options: {\n streamManager: StreamManager,\n type: GroupCallConnectionType,\n options: GroupCallConnectionInstance['options'],\n }) {\n return this.connections[options.type] = new GroupCallConnectionInstance({\n groupCall: this,\n log: this.log.bindPrefix(options.type),\n managers: this.managers,\n ...options\n });\n }\n\n public changeRaiseHand(raise: boolean) {\n return this.editParticipant(this.participant, {raiseHand: raise});\n }\n\n public async startScreenSharingInternal() {\n try {\n const type: GroupCallConnectionType = 'presentation';\n\n const stream = await getScreenStream(getScreenConstraints());\n const streamManager = new StreamManager();\n\n const connectionInstance = this.createConnectionInstance({\n streamManager,\n type,\n options: {\n type\n }\n });\n\n const connection = connectionInstance.createPeerConnection();\n connection.addEventListener('negotiationneeded', () => {\n connectionInstance.negotiate();\n });\n\n stream.getVideoTracks()[0].addEventListener('ended', () => {\n if(this.connections.presentation) { // maybe user has stopped screensharing through browser's ui\n this.stopScreenSharing();\n }\n }, {once: true});\n\n connectionInstance.createDescription();\n connectionInstance.addInputVideoStream(stream);\n } catch(err) {\n this.log.error('start screen sharing error', err);\n }\n }\n\n public startScreenSharing() {\n return this.startScreenSharingPromise ??= this.startScreenSharingInternal().finally(() => {\n this.startScreenSharingPromise = undefined;\n });\n }\n\n public stopScreenSharing() {\n const connectionInstance = this.connections.presentation;\n if(!connectionInstance) {\n return Promise.resolve();\n }\n\n delete this.connections.presentation;\n this.unpinSource('presentation');\n connectionInstance.closeConnectionAndStream(true);\n\n delete this.participant.presentation;\n this.managers.appGroupCallsManager.saveApiParticipant(this.id, this.participant);\n\n return this.managers.appGroupCallsManager.leaveGroupCallPresentation(this.id);\n }\n\n public toggleScreenSharing() {\n if(this.isSharingScreen) {\n return this.stopScreenSharing();\n } else {\n return this.startScreenSharing();\n }\n }\n\n public async startVideoSharingInternal() {\n const constraints: MediaStreamConstraints = {\n video: getVideoConstraints()\n };\n\n try {\n const stream = await getStream(constraints, false);\n const connectionInstance = this.connections.main;\n connectionInstance.addInputVideoStream(stream);\n\n await this.editParticipant(this.participant, {\n videoPaused: false,\n videoStopped: false\n });\n } catch(err) {\n this.log.error('startVideoSharing error', err, constraints);\n }\n }\n\n public startVideoSharing() {\n return this.startVideoSharingPromise ??= this.startVideoSharingInternal().finally(() => {\n this.startVideoSharingPromise = undefined;\n });\n }\n\n public async stopVideoSharing() {\n const connectionInstance = this.connections.main;\n const track = connectionInstance.streamManager.inputStream.getVideoTracks()[0];\n if(!track) {\n return;\n }\n\n stopTrack(track);\n connectionInstance.streamManager.appendToConference(connectionInstance.description); // clear sender track\n\n await this.editParticipant(this.participant, {\n videoStopped: true\n });\n }\n\n public toggleVideoSharing() {\n if(this.isSharingVideo) {\n return this.stopVideoSharing();\n } else {\n return this.startVideoSharing();\n }\n }\n\n public async hangUp(discard = false, rejoin = false, isDiscarded = false) {\n for(const type in this.connections) {\n const connection = this.connections[type as GroupCallConnectionType];\n connection.closeConnectionAndStream(!rejoin);\n }\n\n this.dispatchEvent('state', this.state);\n\n if(isDiscarded) {\n return;\n }\n\n if(!rejoin) {\n const d = discard || (this.joined ? this.connections.main.sources.audio.source : undefined);\n this.managers.appGroupCallsManager.hangUp(this.id, d);\n }\n }\n\n public tryAddTrack(options: Omit<TryAddTrackOptions, 'streamManager'>) {\n const {description} = this;\n const source = super.tryAddTrack(options);\n\n if(options.type === 'output') {\n const entry = description.getEntryBySource(+source);\n this.getParticipantByPeerId(entry.peerId).then((participant) => {\n if(participant) {\n rootScope.dispatchEvent('group_call_participant', {groupCallId: this.id, participant});\n }\n });\n }\n\n return source;\n }\n\n public async editParticipant(participant: GroupCallParticipant, options: Partial<{\n muted: boolean,\n volume: number,\n raiseHand: boolean,\n videoStopped: boolean,\n videoPaused: boolean,\n presentationPaused: boolean\n }>) {\n if(!Object.keys(options).length) {\n return;\n }\n\n // let processUpdate = true;\n if(participant) {\n // const {currentGroupCall} = this;\n // const isCurrentCall = currentGroupCall?.id === groupCallId;\n const isCurrentCall = true;\n const isUpdatingMeInCurrentCall = isCurrentCall && participant.pFlags.self;\n\n if(isUpdatingMeInCurrentCall) {\n if(options.muted !== undefined && !this.isSharingAudio) {\n delete options.muted;\n\n if(!Object.keys(options).length) {\n return;\n }\n }\n }\n\n // if(isCurrentCall) {\n const muted = options.muted;\n if(muted !== undefined) {\n /* const isAdmin = appChatsManager.hasRights(currentGroupCall.chatId, 'manage_call');\n if(isAdmin) {\n if(muted) {\n participant.pFlags.muted = true;\n delete participant.pFlags.can_self_unmute;\n } else {\n participant.pFlags.can_self_unmute = true;\n }\n } else */if(participant.pFlags.self) {\n if(muted) {\n participant.pFlags.muted = true;\n } else if(participant.pFlags.can_self_unmute) {\n delete participant.pFlags.muted;\n }\n }/* else {\n if(muted) {\n participant.pFlags.muted_by_you = true;\n } else {\n delete participant.pFlags.muted_by_you;\n }\n } */\n }\n // }\n\n /* const a: [keyof GroupCallParticipant['pFlags'], keyof typeof options][] = [\n ['muted', 'muted']\n ];\n\n a.forEach(([key, optionKey]) => {\n const value = options[optionKey];\n if(value === undefined) {\n return;\n }\n\n if(value) {\n participant.pFlags[key] = true;\n } else {\n delete participant.pFlags[key];\n }\n }); */\n\n if(options.raiseHand !== undefined) {\n if(options.raiseHand) participant.raise_hand_rating = '1';\n else delete participant.raise_hand_rating;\n }\n\n if(isUpdatingMeInCurrentCall) {\n if(options.videoStopped !== undefined) {\n if(options.videoStopped) delete participant.video;\n else participant.video = generateSelfVideo(this.connections.main.sources.video);\n }\n\n if(!participant.pFlags.muted && participant.pFlags.can_self_unmute) {\n this.setMuted(false);\n }\n\n this.dispatchEvent('state', this.state);\n }\n\n // rootScope.dispatchEvent('group_call_participant', {groupCallId, participant});\n\n /* if(participant.pFlags.self) {\n processUpdate = false;\n } */\n }\n\n return this.managers.appGroupCallsManager.editParticipant(this.id, participant, options);\n }\n\n public onParticipantUpdate(participant: GroupCallParticipant, doNotDispatchParticipantUpdate?: PeerId) {\n const connectionInstance = this.connections.main;\n const {connection, description} = connectionInstance;\n\n const peerId = getPeerId(participant.peer);\n const hasLeft = !!participant.pFlags.left;\n const oldSsrcs = this.participantsSsrcs.get(peerId) || [];\n\n if(participant.presentation && !hasLeft) {\n const {source} = makeSsrcFromParticipant(participant, 'video', participant.presentation.source_groups, participant.presentation.endpoint);\n if(!this.hadAutoPinnedSources.has(source)) {\n this.hadAutoPinnedSources.add(source);\n this.pinSource(participant.pFlags.self ? 'presentation' : source);\n }\n }\n\n if(participant.pFlags.self) {\n this.participant = participant;\n\n if(connectionInstance.sources.audio.source !== participant.source) {\n this.hangUp();\n }\n\n let mute = false;\n if(!participant.pFlags.can_self_unmute) {\n this.stopScreenSharing();\n this.stopVideoSharing();\n mute = true;\n } else if(participant.pFlags.muted) {\n mute = true;\n }\n\n if(mute) {\n this.setMuted(true);\n }\n\n if(doNotDispatchParticipantUpdate !== peerId) {\n this.dispatchEvent('state', this.state);\n }\n\n return;\n }\n\n const ssrcs = hasLeft ? [] : makeSsrcsFromParticipant(participant);\n\n if(!hasLeft) {\n this.participantsSsrcs.set(peerId, ssrcs);\n } else {\n this.participantsSsrcs.delete(peerId);\n }\n\n // const TEST_OLD = false;\n\n const modifiedTypes: Set<WebRTCLineType> = new Set();\n oldSsrcs.forEach((oldSsrc) => {\n const oldSource = oldSsrc.source;\n const newSsrc = ssrcs.find((ssrc) => ssrc.source === oldSource);\n if(!newSsrc) {\n this.unpinSource(oldSource);\n\n const oldEntry = description.getEntryBySource(oldSource);\n if(oldEntry && oldEntry.direction !== 'inactive') {\n oldEntry.setDirection('inactive');\n modifiedTypes.add(oldEntry.type);\n }\n }\n });\n\n ssrcs.forEach((ssrc) => {\n let entry = description.getEntryBySource(ssrc.source);\n if(entry) {\n if(entry.direction === 'inactive') {\n entry.setDirection(entry.originalDirection);\n modifiedTypes.add(entry.type);\n }\n\n return;\n }\n\n entry = description.createEntry(ssrc.type);\n description.setEntrySource(entry, ssrc.sourceGroups || ssrc.source);\n description.setEntryPeerId(entry, peerId);\n\n // if(TEST_OLD) {\n // description.bundleMids.push(entry.mid);\n // entry.setDirection('recvonly');\n // } else {\n ssrc.type === 'video' && entry.setEndpoint(ssrc.endpoint);\n entry.createTransceiver(connection, {direction: 'recvonly'});\n // }\n\n modifiedTypes.add(entry.type);\n });\n\n /* if(TEST_OLD) {\n this.setRemoteOffer({\n connection,\n description,\n ssrcs\n });\n } else */if(modifiedTypes.size) {\n if(modifiedTypes.has('video')) {\n connectionInstance.updateConstraints = true;\n }\n\n connectionInstance.negotiateThrottled();\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nenum GROUP_CALL_STATE {\n UNMUTED,\n MUTED,\n MUTED_BY_ADMIN,\n CONNECTING,\n CLOSED\n}\n\nexport default GROUP_CALL_STATE;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport AudioAssetPlayer from '../../helpers/audioAssetPlayer';\n\nexport type GroupCallAudioAssetName = 'group_call_connect.mp3' | 'group_call_end.mp3' | 'group_call_start.mp3' | 'voip_onallowtalk.mp3';\n\nlet audioAsset: AudioAssetPlayer<GroupCallAudioAssetName>;\nexport default function getGroupCallAudioAsset() {\n return audioAsset ??= new AudioAssetPlayer([\n 'group_call_connect.mp3',\n 'group_call_end.mp3',\n 'group_call_start.mp3',\n 'voip_onallowtalk.mp3'\n ]);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport getGroupCallAudioAsset from '../../components/groupCall/getAudioAsset';\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport EventListenerBase from '../../helpers/eventListenerBase';\nimport {GroupCallParticipant, GroupCallParticipantVideo, GroupCallParticipantVideoSourceGroup} from '../../layer';\nimport {GroupCallId, GroupCallConnectionType} from '../appManagers/appGroupCallsManager';\nimport {AppManagers} from '../appManagers/managers';\nimport {logger} from '../logger';\nimport rootScope from '../rootScope';\nimport GroupCallInstance from './groupCallInstance';\nimport GROUP_CALL_STATE from './groupCallState';\nimport createMainStreamManager from './helpers/createMainStreamManager';\nimport {generateSsrc} from './localConferenceDescription';\nimport {WebRTCLineType} from './sdpBuilder';\nimport StreamManager from './streamManager';\nimport {Ssrc} from './types';\n\nconst IS_MUTED = true;\n\nexport function makeSsrcsFromParticipant(participant: GroupCallParticipant) {\n return [\n makeSsrcFromParticipant(participant, 'audio', participant.source),\n participant.video?.audio_source && makeSsrcFromParticipant(participant, 'audio', participant.video.audio_source),\n participant.video && makeSsrcFromParticipant(participant, 'video', participant.video.source_groups, participant.video.endpoint),\n participant.presentation?.audio_source && makeSsrcFromParticipant(participant, 'audio', participant.presentation.audio_source),\n participant.presentation && makeSsrcFromParticipant(participant, 'video', participant.presentation.source_groups, participant.presentation.endpoint)\n ].filter(Boolean);\n};\n\nexport function makeSsrcFromParticipant(participant: GroupCallParticipant, type: WebRTCLineType, source?: number | GroupCallParticipantVideoSourceGroup[], endpoint?: string): Ssrc {\n return generateSsrc(type, source, endpoint);\n}\n\nexport function generateSelfVideo(source: Ssrc, audioSource?: number): GroupCallParticipantVideo {\n return source && {\n _: 'groupCallParticipantVideo',\n pFlags: {},\n endpoint: '',\n source_groups: source.sourceGroups,\n audio_source: audioSource\n };\n}\n\nexport class GroupCallsController extends EventListenerBase<{\n instance: (instance: GroupCallInstance) => void\n}> {\n private audioAsset: ReturnType<typeof getGroupCallAudioAsset>;\n private log: ReturnType<typeof logger>;\n private currentGroupCall: GroupCallInstance;\n private managers: AppManagers;\n\n public construct(managers: AppManagers) {\n this.managers = managers;\n this.audioAsset = getGroupCallAudioAsset();\n this.log = logger('GCC');\n\n rootScope.addEventListener('group_call_update', (groupCall) => {\n const {currentGroupCall} = this;\n if(currentGroupCall?.id === groupCall.id) {\n currentGroupCall.groupCall = groupCall;\n\n if(groupCall._ === 'groupCallDiscarded') {\n currentGroupCall.hangUp(false, false, true);\n }\n }\n });\n\n rootScope.addEventListener('group_call_participant', ({groupCallId, participant}) => {\n const {currentGroupCall} = this;\n if(currentGroupCall?.id === groupCallId) {\n currentGroupCall.onParticipantUpdate(participant/* , this.doNotDispatchParticipantUpdate */);\n }\n });\n }\n\n get groupCall() {\n return this.currentGroupCall;\n }\n\n public setCurrentGroupCall(groupCall: GroupCallInstance) {\n this.currentGroupCall = groupCall;\n\n if(groupCall) {\n this.dispatchEvent('instance', groupCall);\n }\n }\n\n public startConnectingSound() {\n this.stopConnectingSound();\n this.audioAsset.playSoundWithTimeout('group_call_connect.mp3', true, 2500);\n }\n\n public stopConnectingSound() {\n this.audioAsset.stopSound();\n this.audioAsset.cancelDelayedPlay();\n }\n\n public async joinGroupCall(chatId: ChatId, groupCallId: GroupCallId, muted = IS_MUTED, rejoin?: boolean, joinVideo?: boolean) {\n this.audioAsset.createAudio();\n\n this.log(`joinGroupCall chatId=${chatId} id=${groupCallId} muted=${muted} rejoin=${rejoin}`);\n\n let streamManager: StreamManager;\n if(rejoin) {\n streamManager = this.currentGroupCall.connections.main.streamManager;\n } else {\n streamManager = await createMainStreamManager(muted, joinVideo);\n }\n\n return this.joinGroupCallInternal(chatId, groupCallId, streamManager, muted, rejoin, joinVideo)\n .then(() => {\n // have to refresh participants because of the new connection\n const {currentGroupCall} = this;\n currentGroupCall.participants.then((participants) => {\n if(this.currentGroupCall !== currentGroupCall || currentGroupCall.state === GROUP_CALL_STATE.CLOSED) {\n return;\n }\n\n participants.forEach((participant) => {\n if(!participant.pFlags.self) {\n currentGroupCall.onParticipantUpdate(participant);\n }\n });\n });\n });\n }\n\n private async joinGroupCallInternal(chatId: ChatId, groupCallId: GroupCallId, streamManager: StreamManager, muted: boolean, rejoin = false, joinVideo?: boolean) {\n const log = this.log.bindPrefix('joinGroupCallInternal');\n log('start', groupCallId);\n\n const type: GroupCallConnectionType = 'main';\n\n let {currentGroupCall} = this;\n if(currentGroupCall && rejoin) {\n // currentGroupCall.connections.main.connection = connection;\n currentGroupCall.handleUpdateGroupCallParticipants = false;\n currentGroupCall.updatingSdp = false;\n log('update currentGroupCall', groupCallId, currentGroupCall);\n } else {\n currentGroupCall = new GroupCallInstance({\n chatId,\n id: groupCallId,\n managers: this.managers\n });\n\n currentGroupCall.fixSafariAudio();\n\n currentGroupCall.addEventListener('state', (state) => {\n if(this.currentGroupCall === currentGroupCall && state === GROUP_CALL_STATE.CLOSED) {\n this.setCurrentGroupCall(null);\n this.stopConnectingSound();\n this.audioAsset.playSound('group_call_end.mp3');\n rootScope.dispatchEvent('chat_update', currentGroupCall.chatId);\n }\n });\n\n currentGroupCall.groupCall = await this.managers.appGroupCallsManager.getGroupCallFull(groupCallId);\n\n const connectionInstance = currentGroupCall.createConnectionInstance({\n streamManager,\n type,\n options: {\n type,\n isMuted: muted,\n joinVideo,\n rejoin\n }\n });\n\n const connection = connectionInstance.createPeerConnection();\n connection.addEventListener('negotiationneeded', () => {\n connectionInstance.negotiate();\n });\n\n connection.addEventListener('track', (event) => {\n log('ontrack', event);\n currentGroupCall.onTrack(event);\n });\n\n connection.addEventListener('iceconnectionstatechange', () => {\n currentGroupCall.dispatchEvent('state', currentGroupCall.state);\n\n const {iceConnectionState} = connection;\n if(iceConnectionState === 'disconnected' || iceConnectionState === 'checking' || iceConnectionState === 'new') {\n this.startConnectingSound();\n } else {\n this.stopConnectingSound();\n }\n\n switch(iceConnectionState) {\n case 'checking': {\n break;\n }\n\n case 'closed': {\n currentGroupCall.hangUp();\n break;\n }\n\n case 'completed': {\n break;\n }\n\n case 'connected': {\n if(!currentGroupCall.joined) {\n currentGroupCall.joined = true;\n this.audioAsset.playSound('group_call_start.mp3');\n this.managers.appGroupCallsManager.getGroupCallParticipants(groupCallId);\n }\n\n break;\n }\n\n case 'disconnected': {\n break;\n }\n\n case 'failed': {\n // TODO: replace with ICE restart\n currentGroupCall.hangUp();\n // connection.restartIce();\n break;\n }\n\n case 'new': {\n break;\n }\n }\n });\n\n connectionInstance.createDescription();\n connectionInstance.createDataChannel();\n\n connectionInstance.appendStreamToConference();\n\n this.setCurrentGroupCall(currentGroupCall);\n log('set currentGroupCall', groupCallId, currentGroupCall);\n\n this.startConnectingSound();\n\n return connectionInstance.negotiate();\n }\n }\n}\n\nconst groupCallsController = new GroupCallsController();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.groupCallController = groupCallsController);\nexport default groupCallsController;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {GROUP_CALL_AMPLITUDE_ANALYSE_INTERVAL_MS} from '../constants';\nimport StreamManager from '../streamManager';\nimport getAudioConstraints from './getAudioConstraints';\nimport getStream from './getStream';\nimport getVideoConstraints from './getVideoConstraints';\n\nexport default async function createMainStreamManager(muted?: boolean, joinVideo?: boolean) {\n const constraints: MediaStreamConstraints = {\n audio: getAudioConstraints(),\n video: joinVideo && getVideoConstraints()\n };\n\n const streamManager = new StreamManager(GROUP_CALL_AMPLITUDE_ANALYSE_INTERVAL_MS);\n\n try {\n const stream = await getStream(constraints, muted);\n streamManager.addStream(stream, 'input');\n } catch(err) {\n console.error('joinGroupCall getStream error', err, constraints);\n streamManager.inputStream = new MediaStream();\n }\n\n return streamManager;\n}\n","import constraintSupported, {MyMediaTrackSupportedConstraints} from '../../../environment/constraintSupport';\n\nexport default function getAudioConstraints(): MediaTrackConstraints {\n const constraints: MediaTrackConstraints = {\n channelCount: 2\n };\n\n const desirable: (keyof MyMediaTrackSupportedConstraints)[] = [\n 'noiseSuppression',\n 'echoCancellation',\n 'autoGainControl'\n ];\n\n desirable.forEach((constraint) => {\n if(constraintSupported(constraint)) {\n // @ts-ignore\n constraints[constraint] = true;\n }\n });\n\n return constraints;\n}\n","export type MyMediaTrackSupportedConstraints = MediaTrackSupportedConstraints & {\n noiseSuppression?: boolean,\n autoGainControl?: boolean\n};\n\nexport default function constraintSupported(constraint: keyof MyMediaTrackSupportedConstraints) {\n return (!!navigator?.mediaDevices?.getSupportedConstraints() as any as MyMediaTrackSupportedConstraints)[constraint];\n}\n","export default function getScreenConstraints(skipAudio?: boolean) {\n const constraints: DisplayMediaStreamOptions = {\n video: {\n // @ts-ignore\n // cursor: 'always',\n width: {max: 1920},\n height: {max: 1080},\n frameRate: {max: 30}\n }\n };\n\n if(!skipAudio) {\n constraints.audio = true;\n }\n\n return constraints;\n}\n","export default async function getScreenStream(constraints: DisplayMediaStreamOptions) {\n const screenStream = await navigator.mediaDevices.getDisplayMedia(constraints);\n const track = screenStream.getVideoTracks()[0];\n track.contentHint = 'text';\n return screenStream;\n}\n","export default async function getStream(constraints: MediaStreamConstraints, muted: boolean) {\n // console.log('getStream', constraints);\n\n const stream = await navigator.mediaDevices.getUserMedia(constraints);\n stream.getTracks().forEach((x) => {\n x.enabled = !muted;\n });\n\n // console.log('getStream result', stream);\n return stream;\n}\n\n(window as any).getStream = getStream;\n","export default function getVideoConstraints(): MediaTrackConstraints {\n return {\n width: {min: 1280, max: 1920/* , ideal: 1920 */},\n height: {min: 720, max: 1080/* , ideal: 1080 */},\n frameRate: {min: 24, max: 30}\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport SDP from '../sdp';\nimport SDPMediaSection from '../sdp/mediaSection';\nimport {toTelegramSource} from '../utils';\nimport {parseSourceGroups} from './parseSourceGroups';\n\nexport default function parseMediaSectionInfo(sdp: SDP, channel: SDPMediaSection) {\n const clientInfo = channel.lookupAttributeKeys({\n 'ice-ufrag': true,\n 'ice-pwd': true,\n 'fingerprint': true,\n 'setup': true,\n 'ssrc': true,\n 'mid': true,\n 'ssrc-group': false\n });\n\n if(!clientInfo.fingerprint) { // support Firefox\n const line = sdp.session.lines.find((line) => line.parsed?.key === 'fingerprint');\n clientInfo.fingerprint = line.parsed.value;\n }\n\n const telegramSourceGroups = parseSourceGroups(clientInfo['ssrc-group']);\n const [hash, fingerprint] = clientInfo.fingerprint.split(' ', 2);\n const ssrc = clientInfo.ssrc && toTelegramSource(+clientInfo.ssrc.split(' ', 1)[0]);\n // ssrc = telegramSourceGroups ? telegramSourceGroups[0].sources[0] : ssrc;\n\n return {\n raw: clientInfo,\n ufrag: clientInfo['ice-ufrag'],\n pwd: clientInfo['ice-pwd'],\n fingerprint: {\n fingerprint,\n setup: clientInfo.setup,\n hash\n },\n source: ssrc,\n sourceGroups: telegramSourceGroups,\n mid: clientInfo.mid\n };\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {GroupCallParticipantVideoSourceGroup} from '../../../layer';\nimport {toTelegramSource} from '../utils';\n\nexport function parseSourceGroups(sdpLines: string[]) {\n const telegramSourceGroups = sdpLines.map((str) => {\n const [semantics, ...rest] = str.split(' ');\n\n const sourceGroup: GroupCallParticipantVideoSourceGroup = {\n _: 'groupCallParticipantVideoSourceGroup',\n semantics,\n // sources: rest.map((ssrc) => +ssrc)\n sources: rest.map((ssrc) => toTelegramSource(+ssrc))\n };\n\n return sourceGroup;\n });\n\n /* const simIndex = telegramSourceGroups.findIndex((g) => g.semantics === 'SIM');\n if(simIndex !== -1) {\n const sourceGroup = telegramSourceGroups.splice(simIndex, 1)[0];\n telegramSourceGroups.unshift(sourceGroup);\n } */\n\n return telegramSourceGroups.length ? telegramSourceGroups : undefined;\n}\n","import simulateEvent from '../../../helpers/dom/dispatchEvent';\n\nexport default function stopTrack(track: MediaStreamTrack) {\n track.stop();\n simulateEvent(track, 'ended');\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\nimport indexOfAndSplice from '../../helpers/array/indexOfAndSplice';\nimport safeAssign from '../../helpers/object/safeAssign';\nimport {GroupCallParticipantVideoSourceGroup} from '../../layer';\nimport {fixMediaLineType, SDPBuilder, WebRTCLineType, WEBRTC_MEDIA_PORT} from './sdpBuilder';\nimport {AudioCodec, GroupCallConnectionTransport, Ssrc, UpdateGroupCallConnectionData, VideoCodec} from './types';\n\nexport class ConferenceEntry {\n public source: number;\n public sourceGroups: GroupCallParticipantVideoSourceGroup[];\n public transceiver: RTCRtpTransceiver;\n public originalDirection: RTCRtpTransceiverDirection;\n public direction: RTCRtpTransceiverDirection;\n public port: string;\n public endpoint: string;\n public peerId: PeerId;\n\n public sendEntry: ConferenceEntry;\n public recvEntry: ConferenceEntry;\n\n constructor(public mid: string, public type: WebRTCLineType) {\n this.port = WEBRTC_MEDIA_PORT;\n }\n\n public setDirection(direction: RTCRtpTransceiverDirection) {\n if(!this.originalDirection) {\n this.originalDirection = direction;\n }\n\n return this.direction = direction;\n }\n\n public setPort(port: string) {\n return this.port = port;\n }\n\n public setEndpoint(endpoint: string) {\n return this.endpoint = endpoint;\n }\n\n public setPeerId(peerId: PeerId) {\n return this.peerId = peerId;\n }\n\n public createTransceiver(connection: RTCPeerConnection, init?: RTCRtpTransceiverInit) {\n if(init?.direction) {\n this.setDirection(init.direction);\n }\n\n return this.transceiver = connection.addTransceiver(fixMediaLineType(this.type), init);\n }\n\n public setSource(source: number | GroupCallParticipantVideoSourceGroup[]) {\n let sourceGroups: GroupCallParticipantVideoSourceGroup[];\n if(Array.isArray(source)) {\n if(!source[0]) return;\n sourceGroups = source;\n source = sourceGroups[0].sources[0];\n }\n\n this.sourceGroups = sourceGroups;\n return this.source = source;\n }\n\n public shouldBeSkipped(isAnswer?: boolean) {\n return isAnswer && this.direction === 'inactive';\n }\n}\n\nexport function generateSsrc(type: WebRTCLineType, source: number | GroupCallParticipantVideoSourceGroup[], endpoint?: string): Ssrc {\n let sourceGroups: GroupCallParticipantVideoSourceGroup[];\n if(Array.isArray(source)) {\n if(!source[0]) return;\n sourceGroups = source;\n source = sourceGroups[0].sources[0];\n }\n\n return {\n endpoint,\n type,\n source,\n sourceGroups\n };\n}\n\nexport default class LocalConferenceDescription implements UpdateGroupCallConnectionData {\n public readonly sessionId: string;\n // public ssrcs: Ssrc[];\n public readonly transport: GroupCallConnectionTransport;\n public readonly audio?: AudioCodec;\n public readonly video: VideoCodec;\n public readonly screencast?: VideoCodec;\n\n private maxSeenId: number;\n public readonly entries: ConferenceEntry[];\n private entriesByMid: Map<ConferenceEntry['mid'], ConferenceEntry>;\n private entriesBySource: Map<ConferenceEntry['source'], ConferenceEntry>;\n private entriesByPeerId: Map<ConferenceEntry['peerId'], Set<ConferenceEntry>>;\n\n constructor(public connection: RTCPeerConnection) {\n this.sessionId = '' + Date.now();\n // this.ssrcs = [];\n this.maxSeenId = -1;\n this.entries = [];\n this.entriesByMid = new Map();\n this.entriesBySource = new Map();\n this.entriesByPeerId = new Map();\n }\n\n public setData(data: UpdateGroupCallConnectionData) {\n return safeAssign(this, data);\n }\n\n public createEntry(type: WebRTCLineType) {\n const mid = '' + ++this.maxSeenId;\n const entry = new ConferenceEntry(mid, type);\n this.entries.push(entry);\n this.entriesByMid.set(mid, entry);\n return entry;\n }\n\n public deleteEntry(entry: ConferenceEntry) {\n indexOfAndSplice(this.entries, entry);\n this.entriesByMid.delete(entry.mid);\n this.entriesBySource.delete(entry.source);\n\n const set = this.entriesByPeerId.get(entry.peerId);\n if(set) {\n set.delete(entry);\n if(!set.size) {\n this.entriesByPeerId.delete(entry.peerId);\n }\n }\n }\n\n public setEntrySource(entry: ConferenceEntry, source: Parameters<ConferenceEntry['setSource']>[0]) {\n entry.setSource(source);\n this.entriesBySource.set(entry.source, entry);\n }\n\n public setEntryPeerId(entry: ConferenceEntry, peerId: ConferenceEntry['peerId']) {\n entry.setPeerId(peerId);\n let set = this.entriesByPeerId.get(peerId);\n if(!set) {\n this.entriesByPeerId.set(peerId, set = new Set());\n }\n\n set.add(entry);\n }\n\n public findEntry(verify: Parameters<LocalConferenceDescription['entries']['find']>[0]) {\n return this.entries.find(verify);\n }\n\n public findFreeSendRecvEntry(type: WebRTCLineType, isSending: boolean) {\n let entry = this.entries.find((entry) => {\n return entry.direction === 'sendrecv' && entry.type === type && !(isSending ? entry.sendEntry : entry.recvEntry);\n });\n\n if(!entry) {\n entry = this.createEntry(type);\n entry.setDirection('sendrecv');\n }\n\n return entry;\n }\n\n public getEntryByMid(mid: ConferenceEntry['mid']) {\n return this.entriesByMid.get(mid);\n }\n\n public getEntryBySource(source: ConferenceEntry['source']) {\n return this.entriesBySource.get(source);\n }\n\n public getEntriesByPeerId(peerId: ConferenceEntry['peerId']) {\n return this.entriesByPeerId.get(peerId);\n }\n\n public generateSdp(options: Omit<Parameters<SDPBuilder['addConference']>[0], 'conference'>) {\n return SDPBuilder.fromConference({\n conference: this,\n ...options\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport SDPMediaSection from './mediaSection';\nimport SDPSessionSection from './sessionSection';\n\nexport type AttributeKey = 'group' | 'rtcp' | 'ice-ufrag' |\n 'ice-pwd' | 'ice-options' | 'fingerprint' | 'setup' |\n 'mid' | 'extmap' | 'sendonly' | 'msid' | 'rtcp-mux' |\n 'rtpmap' | 'rtcp-fb' | 'fmtp' | 'ssrc' | 'ssrc-group' |\n 'extmap-allow-mixed' | 'msid-semantic';\n\nexport type AttributeMap = {[k in AttributeKey]?: boolean};\n\nexport default class SDP {\n #session: SDPSessionSection;\n #media: SDPMediaSection[];\n\n constructor(session: SDP['session'], mediaSections: SDP['media']) {\n this.#session = session;\n this.#media = mediaSections;\n }\n\n public get session() {\n return this.#session;\n }\n\n public get media() {\n return this.#media;\n }\n\n public get bundle() {\n const bundleLine = this.session.lines.find((line) => line.parsed?.key === 'group');\n return bundleLine.value.split(' ').slice(1);\n }\n\n toString() {\n return this.session.lines\n .concat(...this.media.map((section) => section.lines))\n .map((line) => line.toString()).join('\\r\\n') + '\\r\\n';\n }\n\n /* get buggedMedia() {\n const bundle = this.bundle;\n type A = {\n mid: SDPMediaSection['mid'],\n mediaType: SDPMediaSection['mediaType'],\n direction: SDPMediaSection['direction']\n };\n const out: A[] = [];\n for(let i = 0, length = this.media.length; i < length; ++i) {\n const section = this.media[i];\n const mid = section.mid;\n if(!bundle.includes(mid)) {\n out.push(section);\n }\n }\n\n return out;\n } */\n\n /* get mediaTypes() {\n return this.media.map((section) => {\n return {mid: section.oa.get('mid').oa, type: section.mediaType, direction: section.direction};\n });\n } */\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default function splitStringByLimitWithRest(str: string, separator: string, limit: number) {\n const splitted = str.split(separator);\n const out: string[] = [];\n\n while(limit > 0 && splitted.length) {\n out.push(splitted.shift());\n --limit;\n }\n\n if(splitted.length) {\n out.push(splitted.join(separator));\n }\n\n return out;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default class UniqueNumberGenerator {\n #set: Set<number>;\n #min: number;\n #max: number;\n\n constructor(min: number, max: number) {\n this.#set = new Set();\n this.#min = min;\n this.#max = max;\n }\n\n public generate() {\n const min = this.#min;\n const max = this.#max;\n const set = this.#set;\n\n const maxTries = max - min + 1;\n let value = Math.floor(min + maxTries * Math.random()), _try = 0;\n while(set.has(value)) {\n if(value < max) {\n ++value;\n } else {\n value = min;\n }\n\n if(++_try >= maxTries) {\n return null;\n }\n }\n\n set.add(value);\n return value;\n }\n\n public add(value: number) {\n this.#set.add(value);\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AttributeKey} from '.';\n\nexport default class SDPAttributeSplitted {\n #key: AttributeKey;\n #value: string;\n\n // key = 'ssrc-group', value = 'SIM 1 2 3'\n constructor(key: AttributeKey, value: string) {\n this.#key = key;\n this.#value = value;\n }\n\n public get key() {\n return this.#key;\n }\n\n public get value() {\n return this.#value;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nexport default class SDPMediaLineParts {\n #type: 'audio' | 'video' | 'application';\n #port: string;\n #protocol: string;\n #ids: string[];\n\n constructor(\n type: SDPMediaLineParts['type'],\n port: SDPMediaLineParts['port'],\n protocol: SDPMediaLineParts['protocol'],\n ids: SDPMediaLineParts['ids']\n ) {\n this.#type = type;\n this.#port = port;\n this.#protocol = protocol;\n this.#ids = ids;\n }\n\n public get type() {\n return this.#type;\n }\n\n public get port() {\n return this.#port;\n }\n\n public get protocol() {\n return this.#protocol;\n }\n\n public get ids() {\n return this.#ids;\n }\n\n toString() {\n return this.type + ' ' + this.port + ' ' + this.protocol + ' ' + this.ids.join(' ');\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport splitStringByLimitWithRest from '../../../helpers/string/splitStringByLimitWithRest';\nimport SDPAttributeSplitted from './attributeSplitted';\nimport SDPMediaLineParts from './mediaLineParts';\n\nexport default class SDPLine {\n #key: 'm' | 'a' | 'o' | 'v' | 's' | 't' | 'c';\n #value: string;\n #mediaLineParts: SDPMediaLineParts;\n #parsed?: SDPAttributeSplitted;\n\n // key = 'a', value = 'ssrc-group:SIM 1 2 3'\n constructor(key: SDPLine['key'], value: string | SDPMediaLineParts | SDPAttributeSplitted) {\n this.#key = key;\n\n if(typeof(value) === 'string') {\n this.#value = value;\n\n if(key === 'm') {\n const splitted = value.split(' ');\n this.#mediaLineParts = new SDPMediaLineParts(splitted[0] as any, splitted[1], splitted[2], splitted.slice(3));\n } else {\n if(key === 'a') {\n const result = splitStringByLimitWithRest(value, ':', 1);\n value = result[0];\n this.#parsed = result.length === 1 ? new SDPAttributeSplitted(value as any, null) : new SDPAttributeSplitted(value as any, result[1]);\n }\n }\n } else {\n if(value instanceof SDPMediaLineParts) {\n this.#mediaLineParts = value;\n this.#value = value.toString();\n } else if(value instanceof SDPAttributeSplitted) {\n this.#parsed = value;\n this.#value = value.value ? `${value.key}:${value.value}` : value.key;\n }\n }\n }\n\n public get key() {\n return this.#key;\n }\n\n public get value() {\n return this.#value;\n }\n\n public get parsed() {\n return this.#parsed;\n }\n\n public get mediaLineParts() {\n return this.#mediaLineParts;\n }\n\n toString() {\n return `${this.key}=${this.value}`;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport splitStringByLimitWithRest from '../../../helpers/string/splitStringByLimitWithRest';\n\nexport default class SDPAttributeInner {\n #key: string;\n #lines: Array<string>;\n #prefix: string;\n #nestedMap: Map<string, SDPAttributeInner>;\n #missed: boolean;\n #keys: Array<string>;\n\n constructor(key: SDPAttributeInner['key'], lines: SDPAttributeInner['lines'], prefix: string = ':', missed = false) {\n this.#key = key;\n this.#lines = lines;\n this.#prefix = prefix;\n this.#missed = missed;\n this.#nestedMap = missed ? new Map() : null;\n this.#keys = missed ? [] : null;\n }\n\n public get lines() {\n return this.#lines;\n }\n\n public get value() {\n return this.#missed || !this.lines.length ? null : this.lines[0];\n }\n\n public get exists() {\n return !this.#missed;\n }\n\n public get key() {\n return this.#key;\n }\n\n public get keys() {\n SDPAttributeInner.fill(this);\n return this.#keys;\n }\n\n public forEach(callback: Parameters<Map<string, SDPAttributeInner>['forEach']>[0]) {\n SDPAttributeInner.fill(this);\n this.#nestedMap.forEach(callback);\n }\n\n public get(key: string) {\n SDPAttributeInner.fill(this);\n return this.#nestedMap.get(key) || new SDPAttributeInner(key, [], ':', true);\n }\n\n private static fill(attribute: SDPAttributeInner) {\n if(attribute.#nestedMap !== null) {\n return;\n }\n\n const map: Map<string, Array<string>> = new Map();\n attribute.lines.forEach((str) => {\n const [key, rest] = splitStringByLimitWithRest(str, attribute.#prefix, 1);\n const values = map.get(key) || [];\n map.set(key, [...values, rest || '']);\n });\n\n const nestedMap = attribute.#nestedMap = SDPAttributeInner.makeAttributes(map);\n attribute.#keys = Array.from(nestedMap.keys());\n }\n\n private static makeAttributes(innerParts: Map<string, Array<string>>) {\n const out: Map<string, SDPAttributeInner> = new Map();\n\n innerParts.forEach((lines, key) => {\n out.set(key, new SDPAttributeInner(key, lines));\n });\n\n return out;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport SDPAttributeInner from './attributeInner';\nimport SDPLine from './line';\n\nexport default class SDPAttributes {\n #lines: SDPLine[];\n #attributes: Map<string, SDPAttributeInner>;\n\n constructor(lines: SDPLine[]) {\n this.#lines = lines;\n this.#attributes = new Map();\n SDPAttributes.fillAttributes(this);\n }\n\n public get(key: string) {\n return this.#attributes.get(key) || new SDPAttributeInner(key, [], ' ', true);\n }\n\n private static fillAttributes(attributes: SDPAttributes) {\n const attributesMap: Map<string, Array<string>> = new Map();\n attributes.#lines.forEach((line) => {\n if(line.key === 'a') {\n const {key, value} = line.parsed;\n\n let linesArray = attributesMap.get(key);\n if(!linesArray) {\n linesArray = [];\n attributesMap.set(key, linesArray);\n }\n\n linesArray.push(value || '');\n }\n });\n\n attributesMap.forEach((linesArray, key) => {\n attributes.#attributes.set(key, new SDPAttributeInner(key, linesArray, ' ', false));\n });\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {AttributeMap} from '.';\nimport {NoExtraProperties} from '../../../types';\nimport SDPAttributes from './attributes';\nimport SDPLine from './line';\n\nexport type SDPMediaDirection = 'sendonly' | 'recvonly' | 'inactive' | 'sendrecv';\nexport default class SDPMediaSection {\n #lines: Array<SDPLine>;\n #mediaLine: SDPLine;\n #attributes: SDPAttributes;\n #direction: SDPMediaDirection;\n\n constructor(lines: Array<SDPLine>) {\n this.#lines = lines;\n this.#mediaLine = lines[0];\n this.#attributes = this.#direction = null;\n }\n\n public get lines() {\n return this.#lines;\n }\n\n public get mediaLine() {\n return this.#mediaLine;\n }\n\n public get mediaLineParts() {\n return this.#mediaLine.mediaLineParts;\n }\n\n public get mediaType() {\n return this.mediaLineParts.type;\n }\n\n public get direction() {\n if(!this.#direction) {\n const attributes = this.attributes;\n\n let direction: SDPMediaDirection;\n if(attributes.get('sendonly').exists) direction = 'sendonly';\n else if(attributes.get('recvonly').exists) direction = 'recvonly';\n else if(attributes.get('inactive').exists) direction = 'inactive';\n else direction = 'sendrecv';\n\n this.#direction = direction;\n }\n\n return this.#direction;\n }\n\n public get isSending() {\n return this.direction === 'sendrecv' || this.direction === 'sendonly';\n }\n\n public get isReceiving() {\n return this.direction === 'sendrecv' || this.direction === 'recvonly';\n }\n\n public get attributes() {\n this.#attributes || (this.#attributes = new SDPAttributes(this.lines));\n return this.#attributes;\n }\n\n public get mid() {\n return this.attributes.get('mid').value;\n }\n\n public lookupAttributeKeys<T extends AttributeMap>(keys: NoExtraProperties<AttributeMap, T>): {[k in keyof T]: T[k] extends true ? string : string[]} {\n const out: any = {};\n\n for(const key in keys) {\n const result = this.attributes.get(key);\n // @ts-ignore\n const resultShouldBeArray = !keys[key];\n if(!result) {\n out[key] = resultShouldBeArray ? [] : undefined;\n } else {\n out[key] = resultShouldBeArray ? result.lines : result.value;\n }\n }\n\n return out;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport SDPLine from './line';\n\nexport default class SDPSessionSection {\n #lines: SDPLine[];\n #sessionId: string;\n\n constructor(lines: SDPLine[]) {\n this.#lines = lines;\n this.#sessionId = lines.filter((line) => line.key === 'o').map((line) => line.value.split(' ')[1])[0];\n }\n\n public get lines() {\n return this.#lines;\n }\n\n public get sessionId() {\n return this.#sessionId;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport SDP from '.';\nimport splitStringByLimitWithRest from '../../../helpers/string/splitStringByLimitWithRest';\nimport UniqueNumberGenerator from '../../../helpers/uniqueNumberGenerator';\nimport SDPLine from './line';\nimport SDPMediaSection from './mediaSection';\nimport SDPSessionSection from './sessionSection';\n\nexport function parseSdp(str: string) {\n function createSection() {\n if(sessionSection) {\n mediaSections.push(new SDPMediaSection(lines));\n } else {\n sessionSection = new SDPSessionSection(lines);\n }\n }\n\n let sessionSection: SDPSessionSection = null, lines: SDPLine[] = [];\n const mediaSections: SDPMediaSection[] = [];\n str.split(/\\r?\\n/).forEach((lineStr) => {\n if(!isIncorrectSdpLine(lineStr)) {\n const line = parseSdpLine(lineStr);\n if(line.key === 'm') {\n createSection();\n lines = [];\n }\n\n lines.push(line);\n }\n });\n\n createSection();\n return new SDP(sessionSection, mediaSections);\n}\n\nexport function isIncorrectSdpLine(str: string) {\n return /^[\\s\\xa0]*$/.test(str);\n}\n\nexport function parseSdpLine(str: string) {\n const splitted = splitStringByLimitWithRest(str, '=', 1);\n return new SDPLine(splitted[0] as any, splitted[1]);\n}\n\nexport function addSimulcast(sdp: SDP) {\n let generator: UniqueNumberGenerator;\n sdp.media.forEach((section, idx) => {\n if(section.mediaType === 'video' && section.isSending && !section.attributes.get('ssrc-group').get('SIM').exists) {\n if(!generator) {\n generator = new UniqueNumberGenerator(2, 4294967295);\n }\n\n const originalSsrcs = section.attributes.get('ssrc-group').get('FID').value.split(' ');\n const lines = section.lines;\n originalSsrcs.forEach((ssrc) => generator.add(+ssrc)); // fix possible duplicates\n const ssrcs = [originalSsrcs[0], generator.generate(), generator.generate()];\n const ssrcs2 = [originalSsrcs[1], generator.generate(), generator.generate()];\n\n lines.push(parseSdpLine('a=ssrc-group:SIM ' + ssrcs.join(' ')));\n\n const ssrcsStrLines = section.attributes.get('ssrc').get(originalSsrcs[0]).lines;\n\n ssrcs.forEach((ssrc, idx) => {\n const ssrc2 = ssrcs2[idx];\n if(idx > 0) {\n lines.push(parseSdpLine('a=ssrc-group:FID ' + ssrc + ' ' + ssrc2));\n\n ssrcsStrLines.forEach((v) => {\n lines.push(parseSdpLine('a=ssrc:' + ssrc + ' ' + v));\n });\n\n ssrcsStrLines.forEach((v) => {\n lines.push(parseSdpLine('a=ssrc:' + ssrc2 + ' ' + v));\n });\n }\n });\n\n sdp.media[idx] = new SDPMediaSection(lines);\n }\n });\n\n return !!generator;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\nimport {IS_FIREFOX} from '../../environment/userAgent';\nimport LocalConferenceDescription, {ConferenceEntry} from './localConferenceDescription';\nimport StringFromLineBuilder from './stringFromLineBuilder';\nimport {GroupCallConnectionTransport, PayloadType, UpdateGroupCallConnectionData} from './types';\nimport {fromTelegramSource} from './utils';\n\n// screencast is for Peer-to-Peer only\nexport type WebRTCLineTypeTrue = 'video' | 'audio' | 'application';\nexport type WebRTCLineType = WebRTCLineTypeTrue | 'screencast';\n\nexport const WEBRTC_MEDIA_PORT = '9';\n\nexport function fixMediaLineType(mediaType: WebRTCLineType) {\n return mediaType === 'screencast' ? 'video' : mediaType;\n}\n\nexport function performCandidate(c: GroupCallConnectionTransport['candidates'][0]) {\n const arr: string[] = [];\n arr.push('a=candidate:');\n arr.push(`${c.foundation} ${c.component} ${c.protocol.toUpperCase()} ${c.priority} ${c.ip} ${c.port} typ ${c.type}`);\n if(c['rel-addr'] !== undefined) {\n arr.push(` raddr ${c['rel-addr']} rport ${c['rel-port']}`);\n }\n arr.push(` generation ${c.generation}`);\n return arr.join('');\n}\n\nexport function getConnectionTypeForMediaType(mediaType: WebRTCLineType) {\n // return mediaType === 'application' ? 'DTLS/SCTP' : 'RTP/SAVPF';\n return mediaType === 'application' ? 'DTLS/SCTP' : 'UDP/TLS/RTP/SAVPF';\n}\n\nexport function generateMediaFirstLine(mediaType: WebRTCLineType, port = WEBRTC_MEDIA_PORT, payloadIds: (string | number)[]) {\n const connectionType = getConnectionTypeForMediaType(mediaType);\n return `m=${fixMediaLineType(mediaType)} ${port} ${connectionType} ${payloadIds.join(' ')}`;\n}\n\ntype ConferenceData = UpdateGroupCallConnectionData | LocalConferenceDescription;\n\n// https://tools.ietf.org/id/draft-ietf-rtcweb-sdp-08.html\n// https://datatracker.ietf.org/doc/html/draft-roach-mmusic-unified-plan-00\nexport class SDPBuilder extends StringFromLineBuilder {\n public addCandidate(c: GroupCallConnectionTransport['candidates'][0]) {\n return this.add(performCandidate(c));\n }\n\n /* public addDataChannel(mid: string, transport: GroupCallConnectionTransport, isAnswer?: boolean) {\n this.add(\n 'm=application 9 UDP/DTLS/SCTP webrtc-datachannel',\n 'c=IN IP4 0.0.0.0',\n 'a=ice-options:trickle',\n `a=mid:${mid}`\n );\n\n // if(!isAnswer) {\n this.add('a=sendrecv');\n // }\n\n this.addTransport(transport, isAnswer);\n\n return this.add(\n 'a=sctp-port:5000',\n 'a=max-message-size:262144'\n );\n } */\n\n public addHeader(sId: string, bundleMids: string[]) {\n const bundle = bundleMids.join(' ');\n return this.add(\n 'v=0', // version\n `o=- ${sId} 2 IN IP4 0.0.0.0`, // sessionId, 2=sessionVersion\n 's=-', // name of the session\n 't=0 0', // time when session is valid\n 'a=extmap-allow-mixed',\n `a=group:BUNDLE ${bundle}`,\n 'a=ice-options:trickle',\n // 'a=ice-lite', // ice-lite: is a minimal version of the ICE specification, intended for servers running on a public IP address.\n 'a=msid-semantic:WMS *'\n );\n }\n\n public addTransport(transport: GroupCallConnectionTransport, skipCandidates?: boolean) {\n this.add(\n `a=ice-ufrag:${transport.ufrag}`,\n `a=ice-pwd:${transport.pwd}`,\n 'a=ice-options:trickle' // ! test\n );\n\n for(const fingerprint of transport.fingerprints) {\n this.add(\n `a=fingerprint:${fingerprint.hash} ${fingerprint.fingerprint}`,\n `a=setup:${fingerprint.setup}`\n );\n }\n\n if(!skipCandidates && transport.candidates) {\n for(const candidate of transport.candidates) {\n this.addCandidate(candidate);\n }\n }\n\n return this;\n }\n\n public addSsrc(entry: ConferenceEntry) {\n let streamName = 'stream';\n let {type, sourceGroups} = entry;\n\n // let source = ssrc.source ?? ssrc.sourceGroups[0].sources[0];\n // source = fromTelegramSource(source);\n const source = fromTelegramSource(entry.source);\n\n streamName += source;\n type += source as any;\n\n // streamName += mid;\n // type += mid as any;\n\n // streamName = type = entry.transceiver.receiver.track.id as any;\n\n const addMsid = () => {\n this.add(`a=msid:${streamName} ${type}`);\n };\n\n const addSource = (ssrc: number) => {\n this.add(\n `a=ssrc:${ssrc} cname:${streamName}`,\n `a=ssrc:${ssrc} msid:${streamName} ${type}`,\n `a=ssrc:${ssrc} mslabel:${streamName}`,\n `a=ssrc:${ssrc} label:${type}`\n );\n };\n\n addMsid();\n if(sourceGroups?.length) {\n sourceGroups.forEach((ssrcGroup) => {\n if(ssrcGroup.sources.length) {\n const sources = ssrcGroup.sources.map(fromTelegramSource);\n this.add(`a=ssrc-group:${ssrcGroup.semantics} ${sources.join(' ')}`);\n sources.forEach(addSource);\n }\n });\n } else {\n addSource(source);\n }\n\n return this;\n }\n\n public addSsrcEntry(entry: ConferenceEntry, data: ConferenceData, isAnswer?: boolean) {\n const add = (...x: string[]) => this.add(...x);\n\n const {type, mid, direction, port} = entry;\n const transport = data.transport;\n\n /* if(type === 'application') {\n return this.addDataChannel(mid, transport, isAnswer);\n } */\n\n const isApplication = type === 'application';\n const codec = isApplication ? undefined : data[type];\n\n const isInactive = direction === 'inactive';\n if(entry.shouldBeSkipped(isAnswer)) {\n return add(\n `m=${fixMediaLineType(type)} 0 ${getConnectionTypeForMediaType(type)} 0`,\n `c=IN IP4 0.0.0.0`,\n `a=inactive`,\n `a=mid:${mid}`\n );\n }\n\n const payloadTypes = !isApplication ? codec['payload-types'] : [{id: 5000} as PayloadType];\n const ids = payloadTypes.map((type) => type.id);\n add(\n generateMediaFirstLine(type, port, ids),\n 'c=IN IP4 0.0.0.0',\n `a=rtcp:${port} IN IP4 0.0.0.0`\n );\n\n if(transport['rtcp-mux']) {\n add('a=rtcp-mux');\n }\n\n add(`a=mid:${mid}`);\n /* if(type === 'video') {\n add('b=AS:2500');\n } */\n\n let setDirection = direction;\n if(direction !== 'sendrecv' && isAnswer && !(isInactive || isApplication)) {\n setDirection = direction === 'sendonly' ? 'recvonly' : 'sendonly';\n }\n\n // a=bundle-only\n add(`a=${setDirection}`);\n\n // this.addTransport(transport, isAnswer);\n this.addTransport(transport);\n\n if(!isApplication) {\n const hdrexts = codec['rtp-hdrexts'];\n if(hdrexts?.length) {\n hdrexts.forEach((hdrext) => {\n add(`a=extmap:${hdrext.id} ${hdrext.uri}`);\n });\n }\n\n payloadTypes.forEach((type) => {\n add(`a=rtpmap:${type.id} ${type.name}/${type.clockrate}${type.channels && type.channels > 1 ? `/${type.channels}` : ''}`);\n\n const parameters = type.parameters;\n if(Array.isArray(parameters)) {\n if(parameters.length) {\n console.error('parameters is array???', parameters);\n }\n } else if(parameters && Object.keys(parameters).length) {\n const p: string[] = [];\n for(const i in parameters) {\n p.push(`${i}=${parameters[i]}`);\n }\n add(`a=fmtp:${type.id} ${p.join(';')}`);\n }\n\n const fbs = type['rtcp-fbs'];\n if(fbs?.length) {\n fbs.forEach((fb) => {\n add(`a=rtcp-fb:${type.id} ${fb.type}${fb.subtype ? ' ' + fb.subtype : ''}`);\n });\n }\n });\n } else {\n add(`a=sctpmap:${payloadTypes[0].id} webrtc-datachannel 256`);\n }\n\n if(entry.source && (setDirection === 'sendonly' || setDirection === 'sendrecv')) {\n this.addSsrc(entry);\n }\n\n return this;\n }\n\n public addConference(options: {\n conference: LocalConferenceDescription,\n bundle: string[],\n entries: ConferenceEntry[],\n isAnswer?: boolean,\n }) {\n const {conference, entries, bundle, isAnswer} = options;\n this.addHeader(conference.sessionId, bundle);\n\n if(IS_FIREFOX) {\n this.addTransport(conference.transport); // support Firefox\n }\n\n for(const entry of entries) {\n // this.addSsrcEntry(entry, conference, isAnswer);\n this.addSsrcEntry((isAnswer ? entry.recvEntry || entry.sendEntry : entry.sendEntry || entry.recvEntry) || entry, conference, isAnswer);\n }\n\n return this;\n }\n\n public static fromConference(options: Parameters<SDPBuilder['addConference']>[0]) {\n return new SDPBuilder().addConference(options).finalize();\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\nimport EventListenerBase from '../../helpers/eventListenerBase';\nimport {logger} from '../logger';\nimport rootScope from '../rootScope';\nimport {GROUP_CALL_AMPLITUDE_ANALYSE_COUNT_MAX} from './constants';\nimport stopTrack from './helpers/stopTrack';\nimport LocalConferenceDescription from './localConferenceDescription';\nimport {fixMediaLineType, WebRTCLineType} from './sdpBuilder';\nimport {getAmplitude, toTelegramSource} from './utils';\n\nexport type StreamItemBase = {\n type: 'input' | 'output',\n track: MediaStreamTrack,\n source: string,\n stream: MediaStream\n};\n\nexport type StreamItem = StreamAudioItem | StreamVideoItem;\n\nexport type StreamAudioItem = StreamItemBase & {kind: 'audio', streamAnalyser: AudioStreamAnalyser};\nexport type StreamVideoItem = StreamItemBase & {kind: 'video'};\n\nexport type StreamAmplitude = {\n type: 'input' | 'output';\n source: string;\n stream: MediaStream;\n track: MediaStreamTrack;\n value: number;\n};\n\nclass AudioStreamAnalyser {\n public analyser: AnalyserNode;\n public gain: GainNode;\n public streamSource: MediaStreamAudioSourceNode;\n\n constructor(context: AudioContext, stream: MediaStream) {\n const streamSource = this.streamSource = context.createMediaStreamSource(stream);\n const analyser = this.analyser = context.createAnalyser();\n const gain = this.gain = context.createGain();\n // const streamDestination = context.createMediaStreamDestination();\n\n analyser.minDecibels = -100;\n analyser.maxDecibels = -30;\n analyser.smoothingTimeConstant = 0.05;\n analyser.fftSize = 1024;\n\n // connect Web Audio API\n streamSource.connect(analyser);\n // analyser.connect(context.destination);\n }\n}\n\nexport default class StreamManager {\n public static ANALYSER_LISTENER = new EventListenerBase<{amplitude: (details: {amplitudes: StreamAmplitude[], type: 'all' | 'input'}) => void}>();\n private context: AudioContext;\n public outputStream: MediaStream;\n public inputStream: MediaStream;\n\n private timer: number;\n private counter: number;\n\n private items: StreamItem[];\n\n private log: ReturnType<typeof logger>;\n\n public direction: RTCRtpTransceiver['direction'];\n public canCreateConferenceEntry: boolean;\n public locked: boolean;\n public types: WebRTCLineType[];\n\n constructor(private interval?: number) {\n this.context = new (window.AudioContext || (window as any).webkitAudioContext)();\n this.items = [];\n this.outputStream = new MediaStream();\n this.inputStream = new MediaStream();\n this.counter = 0;\n this.log = logger('SM');\n this.direction = 'sendonly';\n this.canCreateConferenceEntry = true;\n // this.lol = true;\n this.types = ['audio', 'video'];\n }\n\n public addStream(stream: MediaStream, type: StreamItem['type']) {\n stream.getTracks().forEach((track) => {\n this.addTrack(stream, track, type);\n });\n }\n\n public addTrack(stream: MediaStream, track: MediaStreamTrack, type: StreamItem['type']) {\n this.log('addTrack', type, track, stream);\n\n const {context, items, inputStream, outputStream} = this;\n const kind: StreamItem['kind'] = track.kind as any;\n const source = StreamManager.getSource(stream, type);\n\n // this.removeTrack(track);\n switch(type) {\n case 'input': {\n if(!inputStream) {\n this.inputStream = stream;\n } else {\n inputStream.addTrack(track);\n }\n\n break;\n }\n\n case 'output': {\n for(let i = 0; i < items.length; ++i) {\n const {track: t, type, source: itemSource} = items[i];\n if(itemSource === source && type === 'input') {\n items.splice(i, 1);\n outputStream.removeTrack(t);\n break;\n }\n }\n\n if(kind !== 'video') {\n outputStream.addTrack(track);\n }\n\n break;\n }\n }\n\n this.finalizeAddingTrack({\n type,\n source,\n stream,\n track,\n kind,\n streamAnalyser: kind === 'audio' ? new AudioStreamAnalyser(context, stream) : undefined\n });\n\n if(kind === 'audio' && this.interval) {\n this.changeTimer();\n }\n }\n\n private finalizeAddingTrack(item: StreamItem) {\n const {track} = item;\n track.addEventListener('ended', () => {\n this.removeTrack(track);\n }, {once: true});\n\n this.items.push(item);\n }\n\n public hasInputTrackKind(kind: StreamItem['kind']) {\n return this.items.find((item) => item.type === 'input' && item.kind === kind);\n }\n\n public static getSource(stream: MediaStream, type: StreamItem['type']) {\n return type === 'input' ? (stream.source || stream.id) : '' + toTelegramSource(+stream.id.substring(6));\n }\n\n public removeTrack(track: MediaStreamTrack) {\n this.log('removeTrack', track);\n\n const {items} = this;\n\n let handled = false;\n for(let i = 0, length = items.length; !handled && i < length; ++i) {\n const {track: t, type} = items[i];\n switch(type) {\n case 'output': {\n if(t === track) {\n items.splice(i, 1);\n this.outputStream.removeTrack(track);\n handled = true;\n }\n\n break;\n }\n\n case 'input': {\n if(t === track) {\n items.splice(i, 1);\n this.inputStream.removeTrack(track);\n handled = true;\n }\n\n break;\n }\n }\n }\n\n if(track.kind === 'audio' && this.interval) {\n this.changeTimer();\n }\n }\n\n public replaceInputAudio(stream: MediaStream, oldTrack: MediaStreamTrack) {\n this.removeTrack(oldTrack);\n this.addStream(stream, 'input');\n }\n\n private changeTimer() {\n if(this.timer !== undefined) {\n clearInterval(this.timer);\n }\n\n if(this.items.length) {\n this.timer = window.setInterval(this.analyse, this.interval);\n }\n }\n\n public getAmplitude = (item: StreamAudioItem): StreamAmplitude => {\n const {streamAnalyser, stream, track, source, type} = item;\n const analyser = streamAnalyser.analyser;\n if(!analyser) return;\n\n const array = new Uint8Array(analyser.frequencyBinCount);\n analyser.getByteFrequencyData(array);\n const value = getAmplitude(array);\n\n return {\n type,\n source,\n stream,\n track,\n value\n };\n };\n\n public analyse = () => {\n const all = this.counter % 3 === 0;\n const filteredItems = all ? this.items : this.items.filter((x) => x.type === 'input');\n const audioItems = filteredItems.filter((x) => x.kind === 'audio') as StreamAudioItem[];\n const amplitudes = audioItems.slice(0, GROUP_CALL_AMPLITUDE_ANALYSE_COUNT_MAX).map(this.getAmplitude);\n if(++this.counter >= 1000) {\n this.counter = 0;\n }\n\n StreamManager.ANALYSER_LISTENER.dispatchEvent('amplitude', {\n amplitudes,\n type: all ? 'all' : 'input'\n });\n };\n\n /* public appendToConnection(connection: RTCPeerConnection) {\n if(this.inputStream) {\n this.inputStream.getTracks().forEach((track) => {\n connection.log('addTrack', track);\n connection.addTrack(track, this.inputStream);\n\n if(track.kind === 'video') {\n track.enabled = true;\n }\n });\n }\n } */\n\n public appendToConference(conference: LocalConferenceDescription) {\n if(this.locked) {\n return;\n }\n\n const {inputStream, direction, canCreateConferenceEntry} = this;\n const transceiverInit: RTCRtpTransceiverInit = {direction, streams: [inputStream]};\n const types = this.types.map((type) => {\n return [\n type,\n /* type === 'video' || type === 'screencast' ?\n {sendEncodings: [{maxBitrate: 2500000}], ...transceiverInit} : */\n transceiverInit\n ] as const;\n });\n\n const tracks = inputStream.getTracks();\n // const transceivers = conference.connection.getTransceivers();\n for(const [type, transceiverInit] of types) {\n let entry = conference.findEntry((entry) => entry.direction === direction && entry.type === type);\n if(!entry) {\n if(!canCreateConferenceEntry) {\n continue;\n }\n\n entry = conference.createEntry(type);\n }\n /* const entry = conference.findFreeSendRecvEntry(type, true);\n if(!entry.transceiver) {\n entry.transceiver = transceivers.find((transceiver) => transceiver.mid === entry.mid);\n } */\n\n let {transceiver} = entry;\n if(!transceiver) {\n transceiver = entry.createTransceiver(conference.connection, transceiverInit);\n\n /* if(this.isScreenSharingManager) {\n transceiver.sender.setParameters({\n ...transceiver.sender.getParameters(),\n degradationPreference: 'maintain-resolution'\n });\n } */\n }\n\n if(entry.direction !== transceiver.direction) {\n transceiver.direction = entry.direction;\n }\n\n const mediaTrackType = fixMediaLineType(type);\n const trackIdx = tracks.findIndex((track) => track.kind === mediaTrackType);\n const track = trackIdx !== -1 ? tracks.splice(trackIdx, 1)[0] : undefined;\n const sender = transceiver.sender;\n if(sender.track === track) {\n continue;\n }\n\n // try { // ! don't use await here. it will wait for adding track and fake one won't be visible in startNegotiation.\n /* await */sender.replaceTrack(track).catch((err) => {\n this.log.error(err);\n });\n // } catch(err) {\n\n // }\n }\n }\n\n public stop() {\n try {\n const tracks = this.inputStream.getTracks().concat(this.outputStream.getTracks());\n tracks.forEach((track) => {\n stopTrack(track);\n });\n } catch(e) {\n this.log.error(e);\n }\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\nexport default class StringFromLineBuilder {\n private lines: string[];\n private newLine: string[];\n\n constructor(private joiner = '\\r\\n') {\n this.lines = [];\n this.newLine = [];\n }\n\n public add(...strs: string[]) {\n this.lines.push(...strs);\n return this;\n }\n\n public push(word: string) {\n this.newLine.push(word);\n return this;\n }\n\n public addJoined(separator = '') {\n this.add(this.newLine.join(separator));\n this.newLine = [];\n return this;\n }\n\n public join() {\n return this.lines.join(this.joiner);\n }\n\n public finalize() {\n return this.join() + this.joiner;\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n *\n * Originally from:\n * https://github.com/evgeny-nadymov/telegram-react\n * Copyright (C) 2018 Evgeny Nadymov\n * https://github.com/evgeny-nadymov/telegram-react/blob/master/LICENSE\n */\n\n// NOTE: telegram returns sign source, while webrtc uses unsign source internally\n// unsign => sign\nexport function toTelegramSource(source: number) {\n return source << 0;\n}\n\n// NOTE: telegram returns sign source, while webrtc uses unsign source internally\n// sign => unsign\nexport function fromTelegramSource(source: number) {\n return source >>> 0;\n}\n\nexport function getAmplitude(array: Uint8Array, scale = 3) {\n if(!array) return 0;\n\n const {length} = array;\n let total = 0;\n for(let i = 0; i < length; ++i) {\n total += array[i] * array[i];\n }\n const rms = Math.sqrt(total / length) / 255;\n\n return Math.min(1, rms * scale);\n}\n","export const SEND_WHEN_ONLINE_TIMESTAMP = 0x7FFFFFFE;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MessageEntity} from '../../layer';\nimport getEmojiEntityFromEmoji from './getEmojiEntityFromEmoji';\nimport emojiRegExp from '../../vendor/emoji/regex';\n\nconst EMOJI_REG_EXP = new RegExp(`(^${emojiRegExp})`);\n\nexport default function getAbbreviation(str: string, onlyFirst = false): {\n text: string,\n entities: MessageEntity[]\n} {\n const splitted = (str || '').trim().split(' ');\n if(!splitted[0]) return {text: '', entities: []};\n\n const entities: MessageEntity.messageEntityEmoji[] = [];\n\n const firstEmojiMatch = splitted[0].match(EMOJI_REG_EXP);\n const first = firstEmojiMatch?.[0] || splitted[0][0];\n if(firstEmojiMatch) {\n entities.push(getEmojiEntityFromEmoji(first));\n }\n\n const length = splitted.length;\n if(onlyFirst || length === 1) return {text: first, entities};\n\n const lastEmojiMatch = splitted[length - 1].match(EMOJI_REG_EXP);\n const last = lastEmojiMatch?.[0] || splitted[length - 1][0];\n if(lastEmojiMatch) {\n entities.push({\n ...getEmojiEntityFromEmoji(last),\n offset: first.length\n });\n }\n\n return {text: first + last, entities};\n}\n","import {MessageEntity} from '../../layer';\nimport {toCodePoints} from '../../vendor/emoji';\n\nexport default function getEmojiEntityFromEmoji(emoji: string): MessageEntity.messageEntityEmoji {\n return {\n _: 'messageEntityEmoji',\n offset: 0,\n length: emoji.length,\n unicode: toCodePoints(emoji).join('-').replace(/-?fe0f/g, '')\n };\n}\n","import {EMAIL_REG_EXP} from '.';\n\nexport default function matchEmail(text: string) {\n return !text ? null : text.match(EMAIL_REG_EXP);\n}\n","export default function setBlankToAnchor(anchor: HTMLAnchorElement) {\n anchor.target = '_blank';\n anchor.rel = 'noopener noreferrer';\n return anchor;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport wrapEmojiText from './wrapEmojiText';\nimport getAbbreviation from './getAbbreviation';\n\nexport default function wrapAbbreviation(str: string, onlyFirst?: boolean) {\n const {text, entities} = getAbbreviation(str, onlyFirst);\n return wrapEmojiText(text, undefined, entities);\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport rootScope from '../rootScope';\nimport wrapRichText from './wrapRichText';\n\nexport default function wrapDraftText(text: string, options: Partial<{\n wrappingForPeerId: PeerId\n}> & Parameters<typeof wrapRichText>[1] = {}) {\n if(!text) {\n return wrapRichText('');\n }\n\n let entities = options.entities;\n if(entities && !rootScope.premium && options.wrappingForPeerId !== rootScope.myId) {\n entities = entities.filter((entity) => entity._ !== 'messageEntityCustomEmoji');\n }\n\n const fragment = wrapRichText(text, {\n ...options,\n entities,\n noLinks: true,\n wrappingDraft: true,\n passEntities: {\n messageEntityTextUrl: true,\n messageEntityMentionName: true\n }\n });\n\n return fragment;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport {MessageEntity} from '../../layer';\nimport parseEntities from './parseEntities';\nimport wrapRichText from './wrapRichText';\n\nexport default function wrapEmojiText(text: string, isDraft = false, entities?: MessageEntity[]) {\n if(!text) return wrapRichText('');\n\n entities ??= parseEntities(text).filter((e) => e._ === 'messageEntityEmoji');\n return wrapRichText(text, {entities, wrappingDraft: isDraft});\n}\n","import IS_EMOJI_SUPPORTED from './emojiSupport';\n\nexport type EMOJI_VERSION = '' | '14';\n\nconst EMOJI_VERSIONS_SUPPORTED: {\n [v in EMOJI_VERSION]: boolean\n} = {} as any;\n\n// Thanks to WebZ for the detect\nfunction isEmojiSupported(emoji: string) {\n const ALLOWABLE_CALCULATION_ERROR_SIZE = 5;\n const inlineEl = document.createElement('span');\n inlineEl.classList.add('emoji');\n document.body.appendChild(inlineEl);\n\n inlineEl.innerText = emoji; // Emoji from 14.0 version\n const newEmojiWidth = inlineEl.offsetWidth;\n inlineEl.innerText = '❤️'; // Emoji from 1.0 version\n const legacyEmojiWidth = inlineEl.offsetWidth;\n\n document.body.removeChild(inlineEl);\n\n return Math.abs(newEmojiWidth - legacyEmojiWidth) < ALLOWABLE_CALCULATION_ERROR_SIZE;\n}\n\nif(IS_EMOJI_SUPPORTED) {\n EMOJI_VERSIONS_SUPPORTED[''] = true;\n\n const a: [keyof typeof EMOJI_VERSIONS_SUPPORTED, string][] = [\n ['14', '🫱🏻']\n ];\n\n a.forEach(([version, emoji]) => {\n EMOJI_VERSIONS_SUPPORTED[version] = isEmojiSupported(emoji);\n });\n}\n\nexport default EMOJI_VERSIONS_SUPPORTED;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {EMOJI_VERSION} from '../../environment/emojiVersionsSupport';\nimport {SITE_HASHTAGS} from '.';\nimport {EmojiVersions} from '../../config/emoji';\nimport IS_EMOJI_SUPPORTED from '../../environment/emojiSupport';\nimport buildURLHash from '../../helpers/buildURLHash';\nimport copy from '../../helpers/object/copy';\nimport encodeEntities from '../../helpers/string/encodeEntities';\nimport {MessageEntity} from '../../layer';\nimport encodeSpoiler from './encodeSpoiler';\nimport parseEntities from './parseEntities';\nimport setBlankToAnchor from './setBlankToAnchor';\nimport wrapUrl from './wrapUrl';\nimport EMOJI_VERSIONS_SUPPORTED from '../../environment/emojiVersionsSupport';\nimport {CLICK_EVENT_NAME} from '../../helpers/dom/clickEvent';\nimport IS_CUSTOM_EMOJI_SUPPORTED from '../../environment/customEmojiSupport';\nimport rootScope from '../rootScope';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport wrapSticker, {videosCache} from '../../components/wrappers/sticker';\nimport RLottiePlayer, {getLottiePixelRatio} from '../rlottie/rlottiePlayer';\nimport animationIntersector, {AnimationItemGroup} from '../../components/animationIntersector';\nimport type {MyDocument} from '../appManagers/appDocsManager';\nimport LazyLoadQueue from '../../components/lazyLoadQueue';\nimport {Awaited} from '../../types';\nimport {MediaSize} from '../../helpers/mediaSize';\nimport IS_WEBM_SUPPORTED from '../../environment/webmSupport';\nimport assumeType from '../../helpers/assumeType';\nimport noop from '../../helpers/noop';\nimport findUpClassName from '../../helpers/dom/findUpClassName';\nimport getViewportSlice from '../../helpers/dom/getViewportSlice';\nimport {getMiddleware, Middleware, MiddlewareHelper} from '../../helpers/middleware';\nimport replaceContent from '../../helpers/dom/replaceContent';\nimport BOM from '../../helpers/string/bom';\nimport framesCache from '../../helpers/framesCache';\nimport wrapTelegramUrlToAnchor from './wrapTelegramUrlToAnchor';\nimport {IS_FIREFOX} from '../../environment/userAgent';\n\nconst resizeObserver = new ResizeObserver((entries) => {\n for(const entry of entries) {\n const renderer = entry.target.parentElement as CustomEmojiRendererElement;\n renderer.setDimensionsFromRect(entry.contentRect);\n }\n});\n\nconst globalLazyLoadQueue = new LazyLoadQueue();\n\nexport class CustomEmojiElement extends HTMLElement {\n public elements: CustomEmojiElements;\n public renderer: CustomEmojiRendererElement;\n public player: RLottiePlayer | HTMLVideoElement;\n public paused: boolean;\n public syncedPlayer: SyncedPlayer;\n public clean: boolean;\n public lastChildWas: Node;\n // public docId: DocId;\n public placeholder: HTMLImageElement;\n public middlewareHelper: MiddlewareHelper;\n\n constructor() {\n super();\n this.paused = true;\n this.classList.add('custom-emoji');\n }\n\n public get docId() {\n return this.dataset.docId;\n }\n\n public static create(docId: DocId) {\n const element = new CustomEmojiElement();\n // element.docId = docId;\n element.dataset.docId = '' + docId;\n return element;\n }\n\n public get isConnected() {\n return this.placeholder?.isConnected ?? super.isConnected;\n }\n\n public connectedCallback() {\n // if(this.isConnected) {\n // return;\n // }\n\n if(this.player) {\n animationIntersector.addAnimation({\n animation: this,\n group: this.renderer.animationGroup,\n controlled: true\n });\n }\n\n // this.connectedCallback = undefined;\n }\n\n public disconnectedCallback() {\n if(this.isConnected || !this.renderer?.isSelectable) { // prepend on sibling can invoke disconnectedCallback\n return;\n }\n\n this.clear();\n }\n\n public destroy() {\n this.clear();\n }\n\n public clear(replaceChildren = true) {\n if(this.clean) {\n return;\n }\n\n // if(this.docId === '5399836826758290421') {\n // console.log('clear', this, this.isConnected);\n // }\n\n this.clean = true;\n this.pause();\n\n const {syncedPlayer} = this;\n if(syncedPlayer) {\n syncedPlayer.pausedElements.delete(this);\n }\n\n this.middlewareHelper?.clean();\n\n if(this.renderer) {\n const elements = this.renderer.customEmojis.get(this.docId);\n if(elements?.delete(this) && !elements.size) {\n this.renderer.customEmojis.delete(this.docId);\n this.renderer.playersSynced.delete(elements);\n }\n\n if(replaceChildren) {\n if(this.renderer.isSelectable) {\n this.replaceChildren(createCustomFiller(true));\n } else {\n // otherwise https://bugs.chromium.org/p/chromium/issues/detail?id=1144736#c27 will happen\n this.replaceChildren();\n }\n }\n }\n\n if(this.player) {\n animationIntersector.removeAnimationByPlayer(this);\n }\n\n if(globalLazyLoadQueue) {\n globalLazyLoadQueue.delete({div: this});\n }\n\n /* this.disconnectedCallback = */this.elements =\n this.renderer =\n this.player =\n this.syncedPlayer =\n undefined;\n }\n\n public pause() {\n if(this.paused) {\n return;\n }\n\n this.paused = true;\n\n if(this.player instanceof HTMLVideoElement && !this.syncedPlayer) {\n this.renderer.lastPausedVideo = this.player;\n this.player.pause();\n }\n\n if(this.syncedPlayer && !this.syncedPlayer.pausedElements.has(this)) {\n this.syncedPlayer.pausedElements.add(this);\n\n if(this.syncedPlayer.player && this.syncedPlayer.pausedElements.size === this.syncedPlayer.middlewares.size) {\n this.syncedPlayer.player.pause();\n }\n }\n }\n\n public play() {\n if(!this.paused) {\n return;\n }\n\n this.paused = false;\n\n if(this.player instanceof HTMLVideoElement) {\n this.player.currentTime = this.renderer.lastPausedVideo?.currentTime ?? this.player.currentTime;\n this.player.play().catch(noop);\n }\n\n if(this.syncedPlayer && this.syncedPlayer.pausedElements.has(this)) {\n this.syncedPlayer.pausedElements.delete(this);\n\n if(this.syncedPlayer.pausedElements.size !== this.syncedPlayer.middlewares.size) {\n this.player.play();\n }\n }\n }\n\n public remove() {\n this.clear();\n // this.elements = this.renderer = this.player = undefined;\n }\n\n public get autoplay() {\n return true;\n }\n\n public get loop() {\n return true;\n }\n}\n\ntype CustomEmojiElements = Set<CustomEmojiElement>;\n\nexport class CustomEmojiRendererElement extends HTMLElement {\n public canvas: HTMLCanvasElement;\n public context: CanvasRenderingContext2D;\n\n public playersSynced: Map<CustomEmojiElements, RLottiePlayer | HTMLVideoElement>;\n public clearedElements: WeakSet<CustomEmojiElements>;\n public customEmojis: Parameters<typeof wrapRichText>[1]['customEmojis'];\n public lastPausedVideo: HTMLVideoElement;\n\n public lastRect: DOMRect;\n public isDimensionsSet: boolean;\n\n public animationGroup: AnimationItemGroup;\n public size: MediaSize;\n\n public isSelectable: boolean;\n public isCanvasClean: boolean;\n\n public ignoreSettingDimensions: boolean;\n\n public forceRenderAfterSize: boolean;\n\n public middlewareHelper: MiddlewareHelper;\n\n public auto: boolean;\n\n constructor() {\n super();\n\n this.classList.add('custom-emoji-renderer');\n this.canvas = document.createElement('canvas');\n this.canvas.classList.add('custom-emoji-canvas');\n this.context = this.canvas.getContext('2d');\n this.append(this.canvas);\n\n this.playersSynced = new Map();\n this.clearedElements = new WeakSet();\n this.customEmojis = new Map();\n\n this.animationGroup = 'EMOJI';\n this.isCanvasClean = false;\n }\n\n public connectedCallback() {\n if(emojiRenderers.has(this)) {\n return;\n }\n\n // this.setDimensions();\n // animationIntersector.addAnimation(this, this.animationGroup);\n resizeObserver.observe(this.canvas);\n emojiRenderers.add(this);\n\n this.connectedCallback = undefined;\n }\n\n public disconnectedCallback() {\n if(this.isConnected || !this.auto) {\n return;\n }\n\n this.destroy?.();\n\n this.disconnectedCallback = undefined;\n }\n\n public destroy() {\n // if(this.isConnected) {\n // return;\n // }\n\n resizeObserver.unobserve(this.canvas);\n\n this.customEmojis.forEach((elements) => {\n elements.forEach((element) => {\n element.clear();\n });\n });\n\n emojiRenderers.delete(this);\n this.playersSynced.clear();\n this.middlewareHelper?.clean();\n this.customEmojis.clear();\n\n this.destroy =\n this.lastPausedVideo =\n undefined;\n }\n\n public getOffsets(offsetsMap: Map<CustomEmojiElements, {top: number, left: number, width: number}[]> = new Map()) {\n if(!this.playersSynced.size) {\n return offsetsMap;\n }\n\n const overflowElement = findUpClassName(this, 'scrollable') || this.offsetParent as HTMLElement;\n if(!overflowElement) {\n return offsetsMap;\n }\n\n const overflowRect = overflowElement.getBoundingClientRect();\n const rect = this.getBoundingClientRect();\n\n for(const elements of this.playersSynced.keys()) {\n const elementsArr = Array.from(elements);\n const placeholders = this.isSelectable ? elementsArr.map((element) => element.placeholder) : elementsArr;\n const {visible} = getViewportSlice({\n overflowElement,\n overflowRect,\n elements: placeholders,\n extraSize: this.size.height * 2.5 // let's add some margin\n });\n\n const offsets = visible.map(({rect: elementRect}) => {\n const top = elementRect.top - rect.top;\n const left = elementRect.left - rect.left;\n return {top, left, width: elementRect.width};\n });\n\n if(offsets.length) {\n offsetsMap.set(elements, offsets);\n }\n }\n\n // const rect = this.getBoundingClientRect();\n // const visibleRect = getVisibleRect(this, overflowElement, undefined, rect);\n // const minTop = visibleRect ? visibleRect.rect.top - this.size.height : 0;\n // const maxTop = Infinity;\n // for(const elements of this.playersSynced.keys()) {\n // const offsets = elements.map((element) => {\n // const elementRect = element.getBoundingClientRect();\n // const top = elementRect.top - rect.top;\n // const left = elementRect.left - rect.left;\n // return top >= minTop && (top + elementRect.height) <= maxTop ? {top, left} : undefined;\n // }).filter(Boolean);\n\n // if(offsets.length) {\n // offsetsMap.set(elements, offsets);\n // }\n // }\n\n return offsetsMap;\n }\n\n public clearCanvas() {\n if(this.isCanvasClean) {\n return;\n }\n\n const {context, canvas} = this;\n context.clearRect(0, 0, canvas.width, canvas.height);\n this.isCanvasClean = true;\n }\n\n public render(offsetsMap: ReturnType<CustomEmojiRendererElement['getOffsets']>) {\n const {context, canvas, isDimensionsSet} = this;\n if(!isDimensionsSet) {\n this.setDimensionsFromRect(undefined, false);\n }\n\n this.isCanvasClean = false;\n\n const {width, height, dpr} = canvas;\n for(const [elements, offsets] of offsetsMap) {\n const player = this.playersSynced.get(elements);\n const frame = syncedPlayersFrames.get(player) || (player instanceof HTMLVideoElement ? player : undefined);\n if(!frame) {\n continue;\n }\n\n const isImageData = frame instanceof ImageData;\n let frameWidth: number, frameHeight: number;\n if(player instanceof HTMLVideoElement) {\n frameWidth = this.size.width * dpr;\n frameHeight = this.size.height * dpr;\n } else {\n frameWidth = frame.width;\n frameHeight = frame.height;\n }\n\n // ! check performance of scaling\n const elementWidth = Math.round(offsets[0].width * dpr);\n if(elementWidth !== frameWidth) {\n // if(this.size.width === 36) {\n // console.warn('different width', elementWidth, frameWidth, this);\n // }\n\n frameWidth = elementWidth;\n frameHeight = elementWidth;\n }\n\n const maxTop = height - frameHeight;\n const maxLeft = width - frameWidth;\n\n if(!this.clearedElements.has(elements) && !this.isSelectable) {\n if(this.isSelectable/* && false */) {\n elements.forEach((element) => {\n element.lastChildWas ??= element.lastChild;\n replaceContent(element, element.firstChild);\n });\n } else {\n elements.forEach((element) => {\n element.replaceChildren();\n });\n }\n\n this.clearedElements.add(elements);\n }\n\n offsets.forEach(({top, left}) => {\n top = Math.round(top * dpr), left = Math.round(left * dpr);\n if(left < 0 ||/* top > maxTop || */left > maxLeft) {\n return;\n }\n\n if(isImageData) {\n context.putImageData(frame, left, top);\n } else {\n // context.clearRect(left, top, width, height);\n context.drawImage(frame, left, top, frameWidth, frameHeight);\n }\n });\n }\n }\n\n public checkForAnyFrame() {\n for(const player of this.playersSynced.values()) {\n if(syncedPlayersFrames.has(player) || player instanceof HTMLVideoElement) {\n return true;\n }\n }\n\n return false;\n }\n\n public remove() {\n super.remove();\n // this.canvas.remove();\n }\n\n // public setDimensions() {\n // const {canvas} = this;\n // sequentialDom.mutateElement(canvas, () => {\n // const rect = canvas.getBoundingClientRect();\n // this.setDimensionsFromRect(rect);\n // });\n // }\n\n public setDimensionsFromRect(rect: DOMRect = this.lastRect, forceRenderAfter = true) {\n const {canvas} = this;\n const {dpr} = canvas;\n\n if(this.lastRect !== rect) {\n this.lastRect = rect;\n }\n\n if(!rect || !dpr || this.ignoreSettingDimensions) {\n return;\n }\n\n const {width, height} = rect;\n // if(this.isSelectable) {\n // height = this.parentElement.scrollHeight || height;\n\n // this.style.width = width + 'px';\n // this.style.height = height + 'px';\n // }\n\n const newWidth = Math.floor(Math.round(width * dpr));\n const newHeight = Math.floor(Math.round(height * dpr));\n if(canvas.width === newWidth && canvas.height === newHeight) {\n return;\n }\n\n canvas.width = newWidth;\n canvas.height = newHeight;\n this.isDimensionsSet = true;\n this.isCanvasClean = true;\n\n if(this.forceRenderAfterSize || (this.isSelectable && forceRenderAfter)) {\n this.forceRenderAfterSize = undefined;\n this.forceRender();\n }\n }\n\n public forceRender() {\n if(!this.isDimensionsSet) {\n return;\n }\n\n if(!renderEmojis(new Set([this]))) {\n this.clearCanvas();\n }\n }\n\n public add(\n addCustomEmojis: Parameters<typeof wrapRichText>[1]['customEmojis'],\n lazyLoadQueue?: LazyLoadQueue | false,\n onlyThumb?: boolean,\n withThumb?: boolean\n ) {\n const renderer = this;\n\n addCustomEmojis.forEach((addElements, docId) => { // prevent adding old elements\n let elements = this.customEmojis.get(docId);\n if(!elements) this.customEmojis.set(docId, elements = new Set());\n else this.clearedElements.delete(elements);\n\n for(const el of addElements) {\n if(elements.has(el)) {\n addElements.delete(el);\n } else {\n el.clean = false;\n el.renderer = renderer;\n el.elements = elements;\n el.middlewareHelper = this.middlewareHelper.get().create();\n elements.add(el);\n\n if(el.lastChildWas && !el.lastChildWas.parentNode) {\n el.append(el.lastChildWas);\n }\n }\n }\n\n if(!addElements.size) {\n addCustomEmojis.delete(docId);\n }\n });\n\n if(!addCustomEmojis.size) {\n return;\n }\n\n const usingOwnQueue = !!(!lazyLoadQueue && lazyLoadQueue !== false && globalLazyLoadQueue);\n\n const docIds = Array.from(addCustomEmojis.keys());\n\n const managers = rootScope.managers;\n const middleware = this.middlewareHelper.get();\n const size = this.size;\n\n const loadPromise = managers.appEmojiManager.getCachedCustomEmojiDocuments(docIds).then((docs) => {\n if(middleware && !middleware()) return;\n\n const loadPromises: Promise<any>[] = [];\n const wrap = (doc: MyDocument, _loadPromises?: Promise<any>[]) => {\n const docId = doc.id;\n const newElements = addCustomEmojis.get(docId);\n const customEmojis = renderer.customEmojis.get(docId);\n const isLottie = doc.sticker === 2;\n const isStatic = doc.mime_type === 'video/webm' && !IS_WEBM_SUPPORTED;\n const willHaveSyncedPlayer = (isLottie || (doc.sticker === 3 && this.isSelectable)) && !onlyThumb && !isStatic;\n\n const loadPromises: Promise<any>[] = [];\n const newElementsArray = Array.from(newElements);\n const promise = wrapSticker({\n div: newElementsArray,\n doc,\n width: size.width,\n height: size.height,\n loop: true,\n play: CUSTOM_EMOJI_INSTANT_PLAY,\n managers,\n isCustomEmoji: true,\n group: 'none',\n loadPromises,\n middleware,\n exportLoad: usingOwnQueue || lazyLoadQueue === false ? 2 : 1, // 2 - export load always, 1 - do not export load if cached static\n needFadeIn: false,\n loadStickerMiddleware: willHaveSyncedPlayer && middleware ? middleware.create().get(() => {\n // if(syncedPlayers.get(key) !== syncedPlayer) {\n // return false;\n // }\n\n // let good = false;\n // for(const middleware of syncedPlayer.middlewares) {\n // if(middleware()) {\n // good = true;\n // break;\n // }\n // }\n\n // return good;\n return !!syncedPlayer.middlewares.size;\n }) : undefined,\n static: isStatic,\n onlyThumb,\n withThumb: withThumb ?? (renderer.clearedElements.has(customEmojis) ? false : undefined),\n syncedVideo: this.isSelectable\n });\n\n if(_loadPromises) {\n promise.then(() => _loadPromises.push(...loadPromises));\n }\n\n const addition: {\n onRender?: (_p: Awaited<Awaited<typeof promise>['render']>) => Promise<void>,\n elements: typeof newElements\n } = {\n elements: newElements\n };\n\n if(doc.sticker === 1 || onlyThumb || isStatic) {\n if(this.isSelectable) {\n addition.onRender = () => Promise.all(loadPromises).then(() => {\n if(middleware && !middleware()) return;\n newElementsArray.forEach((element) => {\n const {placeholder} = element;\n placeholder.src = (element.firstElementChild as HTMLImageElement).src;\n });\n });\n }\n\n return promise.then((res) => ({...res, ...addition}));\n }\n\n // eslint-disable-next-line prefer-const\n addition.onRender = (_p) => Promise.all(loadPromises).then(() => {\n if((middleware && !middleware()) || !doc.animated) {\n return;\n }\n\n const players = Array.isArray(_p) ? _p as HTMLVideoElement[] : [_p as RLottiePlayer];\n const player = Array.isArray(players) ? players[0] : players;\n assumeType<RLottiePlayer | HTMLVideoElement>(player);\n newElementsArray.forEach((element, idx) => {\n const player = players[idx] || players[0];\n element.player = player;\n\n if(syncedPlayer) {\n element.syncedPlayer = syncedPlayer;\n if(element.paused) {\n element.syncedPlayer.pausedElements.add(element);\n } else if(player.paused) {\n player.play();\n }\n }\n\n if(element.isConnected) {\n animationIntersector.addAnimation({\n animation: element,\n group: element.renderer.animationGroup,\n controlled: true\n });\n }\n });\n\n if(player instanceof RLottiePlayer || (player instanceof HTMLVideoElement && this.isSelectable)) {\n syncedPlayer.player = player;\n renderer.playersSynced.set(customEmojis, player);\n }\n\n if(player instanceof RLottiePlayer) {\n player.group = renderer.animationGroup;\n\n player.overrideRender ??= (frame) => {\n syncedPlayersFrames.set(player, frame);\n // frames.set(containers, frame);\n };\n } else if(player instanceof HTMLVideoElement) {\n // player.play();\n\n // const cache = framesCache.getCache(key);\n // let {width, height} = renderer.size;\n // width *= dpr;\n // height *= dpr;\n\n // const onFrame = (frame: ImageBitmap | HTMLCanvasElement) => {\n // topFrames.set(player, frame);\n // player.requestVideoFrameCallback(callback);\n // };\n\n // let frameNo = -1, lastTime = 0;\n // const callback: VideoFrameRequestCallback = (now, metadata) => {\n // const time = player.currentTime;\n // if(lastTime > time) {\n // frameNo = -1;\n // }\n\n // const _frameNo = ++frameNo;\n // lastTime = time;\n // // const frameNo = Math.floor(player.currentTime * 1000 / CUSTOM_EMOJI_FRAME_INTERVAL);\n // // const frameNo = metadata.presentedFrames;\n // const imageBitmap = cache.framesNew.get(_frameNo);\n\n // if(imageBitmap) {\n // onFrame(imageBitmap);\n // } else if(IS_IMAGE_BITMAP_SUPPORTED) {\n // createImageBitmap(player, {resizeWidth: width, resizeHeight: height}).then((imageBitmap) => {\n // cache.framesNew.set(_frameNo, imageBitmap);\n // if(frameNo === _frameNo) onFrame(imageBitmap);\n // });\n // } else {\n // const canvas = document.createElement('canvas');\n // const context = canvas.getContext('2d');\n // canvas.width = width;\n // canvas.height = height;\n // context.drawImage(player, 0, 0);\n // cache.framesNew.set(_frameNo, canvas);\n // onFrame(canvas);\n // }\n // };\n\n // // player.requestVideoFrameCallback(callback);\n // // setInterval(callback, CUSTOM_EMOJI_FRAME_INTERVAL);\n }\n\n if(willHaveSyncedPlayer) {\n const dpr = getLottiePixelRatio(this.size.width, this.size.height);\n renderer.canvas.dpr = dpr;\n setRenderInterval();\n }\n });\n\n let syncedPlayer: SyncedPlayer;\n const key = [docId, size.width, size.height].join('-');\n if(willHaveSyncedPlayer) {\n syncedPlayer = syncedPlayers.get(key);\n if(!syncedPlayer) {\n syncedPlayer = {\n player: undefined,\n middlewares: new Set(),\n pausedElements: new Set(),\n key\n };\n\n syncedPlayers.set(key, syncedPlayer);\n }\n\n for(const element of newElements) {\n const middleware = element.middlewareHelper.get();\n syncedPlayer.middlewares.add(middleware);\n middleware.onClean(() => {\n syncedPlayer.middlewares.delete(middleware);\n\n if(!syncedPlayer.middlewares.size) {\n if(syncedPlayer.player) {\n const frame = syncedPlayersFrames.get(syncedPlayer.player);\n if(frame) {\n (frame as ImageBitmap).close?.();\n syncedPlayersFrames.delete(syncedPlayer.player);\n }\n\n syncedPlayersFrames.delete(syncedPlayer.player);\n if(syncedPlayer.player instanceof RLottiePlayer) {\n syncedPlayer.player.overrideRender = noop;\n syncedPlayer.player.remove();\n } else if(syncedPlayer.player instanceof HTMLVideoElement) {\n const cacheName = framesCache.generateName('' + element.docId, 0, 0, undefined, undefined);\n delete videosCache[cacheName];\n }\n\n syncedPlayer.player = undefined;\n }\n\n if(syncedPlayers.get(syncedPlayer.key) === syncedPlayer && syncedPlayers.delete(syncedPlayer.key) && !syncedPlayers.size) {\n clearRenderInterval();\n }\n }\n });\n }\n }\n\n return promise.then((res) => ({...res, ...addition}));\n };\n\n const missing: DocId[] = [];\n const cachedPromises = docs.map((doc, idx) => {\n if(!doc) {\n missing.push(docIds[idx]);\n return;\n }\n\n return wrap(doc, loadPromises);\n }).filter(Boolean);\n\n const uncachedPromisesPromise = !missing.length ?\n Promise.resolve([] as typeof cachedPromises) :\n managers.appEmojiManager.getCustomEmojiDocuments(missing).then((docs) => {\n if(middleware && !middleware()) return [];\n return docs.filter(Boolean).map((doc) => wrap(doc));\n });\n\n const loadFromPromises = (promises: typeof cachedPromises) => {\n return Promise.all(promises).then((arr) => {\n const promises = arr.map(({load, onRender, elements}) => {\n if(!load) {\n return;\n }\n\n const l = () => load().then(onRender);\n\n if(usingOwnQueue) {\n elements.forEach((element) => {\n globalLazyLoadQueue.push({\n div: element,\n load: () => {\n elements.forEach((element) => {\n globalLazyLoadQueue.delete({div: element});\n });\n\n return l();\n }\n });\n });\n } else {\n return l();\n }\n });\n\n return Promise.all(promises);\n });\n };\n\n const load = () => {\n if(middleware && !middleware()) return;\n const cached = loadFromPromises(cachedPromises);\n const uncached = uncachedPromisesPromise.then((promises) => loadFromPromises(promises));\n return Promise.all([cached, uncached]);\n };\n\n if(lazyLoadQueue) {\n lazyLoadQueue.push({\n div: renderer.canvas,\n load\n });\n } else {\n load();\n }\n\n return Promise.all(cachedPromises).then(() => Promise.all(loadPromises)).then(() => {});\n });\n\n // recordPromise(loadPromise, 'render emojis: ' + docIds.length);\n\n return loadPromise;\n }\n\n public static create(options: CustomEmojiRendererElementOptions) {\n const renderer = new CustomEmojiRendererElement();\n renderer.animationGroup = options.animationGroup;\n renderer.size = options.customEmojiSize || mediaSizes.active.customEmoji;\n renderer.isSelectable = options.isSelectable;\n if(options.wrappingDraft) {\n renderer.contentEditable = 'false';\n renderer.style.height = 'inherit';\n }\n // const middleware = () => !!renderer.disconnectedCallback && (!options.middleware || options.middleware());\n let middleware = options.middleware;\n if(middleware) {\n renderer.middlewareHelper = middleware.create();\n middleware = renderer.middlewareHelper.get();\n middleware.onDestroy(() => {\n renderer.destroy?.();\n });\n } else {\n // console.error('no middleware', this, options);\n renderer.auto = true;\n renderer.middlewareHelper = getMiddleware();\n }\n\n return renderer;\n }\n}\n\ntype CustomEmojiRenderer = CustomEmojiRendererElement;\ntype SyncedPlayer = {\n player: RLottiePlayer | HTMLVideoElement,\n middlewares: Set<Middleware>,\n pausedElements: Set<CustomEmojiElement>,\n key: string\n};\ntype CustomEmojiFrame = Parameters<RLottiePlayer['overrideRender']>[0] | HTMLVideoElement;\n\nconst CUSTOM_EMOJI_INSTANT_PLAY = true; // do not wait for animationIntersector\nlet emojiRenderInterval: number;\nconst emojiRenderers: Set<CustomEmojiRenderer> = new Set();\nconst syncedPlayers: Map<string, SyncedPlayer> = new Map();\nconst syncedPlayersFrames: Map<RLottiePlayer | HTMLVideoElement, CustomEmojiFrame> = new Map();\nexport const renderEmojis = (renderers = emojiRenderers) => {\n const r = Array.from(renderers);\n const t = r.filter((r) => r.isConnected && r.checkForAnyFrame() && !r.ignoreSettingDimensions);\n if(!t.length) {\n return false;\n }\n\n const o = t.map((renderer) => {\n const paused = [...renderer.playersSynced.values()].reduce((acc, v) => acc + +!!v.paused, 0);\n if(renderer.playersSynced.size === paused) {\n return;\n }\n\n const offsets = renderer.getOffsets();\n if(offsets.size) {\n return [renderer, offsets] as const;\n }\n }).filter(Boolean);\n\n for(const [renderer] of o) {\n renderer.clearCanvas();\n }\n\n for(const [renderer, offsets] of o) {\n renderer.render(offsets);\n }\n\n return true;\n};\nconst CUSTOM_EMOJI_FPS = 60;\nconst CUSTOM_EMOJI_FRAME_INTERVAL = 1000 / CUSTOM_EMOJI_FPS;\nconst setRenderInterval = () => {\n if(emojiRenderInterval) {\n return;\n }\n\n emojiRenderInterval = window.setInterval(renderEmojis, CUSTOM_EMOJI_FRAME_INTERVAL);\n renderEmojis();\n};\nconst clearRenderInterval = () => {\n if(!emojiRenderInterval) {\n return;\n }\n\n clearInterval(emojiRenderInterval);\n emojiRenderInterval = undefined;\n};\n\n(window as any).syncedPlayers = syncedPlayers;\n(window as any).emojiRenderers = emojiRenderers;\n\ncustomElements.define('custom-emoji-element', CustomEmojiElement);\ncustomElements.define('custom-emoji-renderer-element', CustomEmojiRendererElement);\n\ntype CustomEmojiRendererElementOptions = Partial<{\n loadPromises: Promise<any>[],\n customEmojiRenderer: CustomEmojiRendererElement,\n\n isSelectable: boolean,\n wrappingDraft: boolean\n}> & WrapSomethingOptions;\n\n/**\n * * Expecting correctly sorted nested entities (RichTextProcessor.sortEntities)\n */\nexport default function wrapRichText(text: string, options: Partial<{\n entities: MessageEntity[],\n contextSite: string,\n highlightUsername: string,\n noLinks: boolean,\n noLinebreaks: boolean,\n noCommands: boolean,\n wrappingDraft: boolean,\n // mustWrapEmoji: boolean,\n fromBot: boolean,\n noTextFormat: boolean,\n passEntities: Partial<{\n [_ in MessageEntity['_']]: boolean\n }>,\n maxMediaTimestamp: number,\n noEncoding: boolean,\n isSelectable: boolean,\n\n contextHashtag?: string,\n\n // ! recursive, do not provide\n nasty?: {\n i: number,\n usedLength: number,\n text: string,\n lastEntity?: MessageEntity\n },\n voodoo?: boolean,\n customEmojis?: Map<DocId, CustomEmojiElements>,\n customWraps?: Set<HTMLElement>,\n}> & CustomEmojiRendererElementOptions = {}) {\n const fragment = document.createDocumentFragment();\n if(!text) {\n return fragment;\n }\n\n const nasty = options.nasty ??= {\n i: 0,\n usedLength: 0,\n text\n };\n\n const wrapSomething = (wrapElement: HTMLElement, noFiller?: boolean) => {\n const element = document.createElement('span');\n // element.append(BOM, a, BOM);\n if(options.wrappingDraft) {\n element.contentEditable = 'false';\n }\n // element.style.display = 'inline-block';\n element.classList.add('input-something');\n element.append(/* BOM, */wrapElement);\n\n (lastElement || fragment).append(element);\n\n wrapElement.classList.add('input-selectable');\n // if(wrapElement instanceof HTMLImageElement) {\n // element.prepend(f());\n // } else {\n !noFiller && wrapElement.append(createCustomFiller(true));\n // }\n\n customWraps.add(element);\n\n return element;\n };\n\n options.isSelectable ||= options.wrappingDraft;\n\n const customEmojis = options.customEmojis ??= new Map() as Map<DocId, CustomEmojiElements>;\n const customWraps = options.customWraps ??= new Set();\n\n const entities = options.entities ??= parseEntities(nasty.text);\n\n const passEntities = options.passEntities ??= {};\n const contextSite = options.contextSite ??= 'Telegram';\n const contextExternal = contextSite !== 'Telegram';\n\n const textLength = nasty.text.length;\n const length = entities.length;\n let lastElement: HTMLElement | DocumentFragment;\n for(; nasty.i < length; ++nasty.i) {\n let entity = entities[nasty.i];\n\n // * check whether text was sliced\n // TODO: consider about moving it to other function\n if(entity.offset >= textLength) {\n if(entity._ !== 'messageEntityCaret') { // * can set caret to the end\n continue;\n }\n } else if((entity.offset + entity.length) > textLength) {\n entity = copy(entity);\n // entity.length = entity.offset + entity.length - textLength;\n entity.length = textLength - entity.offset;\n }\n\n if(entity.length) {\n nasty.lastEntity = entity;\n }\n\n let nextEntity = entities[nasty.i + 1];\n\n const startOffset = entity.offset;\n const endOffset = startOffset + entity.length;\n const endPartOffset = Math.min(endOffset, nextEntity?.offset ?? 0xFFFF);\n const fullEntityText = nasty.text.slice(startOffset, endOffset);\n const sliced = nasty.text.slice(startOffset, endPartOffset);\n let partText = sliced;\n\n if(nasty.usedLength < startOffset) {\n (lastElement || fragment).append(nasty.text.slice(nasty.usedLength, startOffset));\n }\n\n if(lastElement) {\n lastElement = fragment;\n }\n\n nasty.usedLength = endPartOffset;\n\n let element: HTMLElement,\n property: 'textContent' | 'alt' = 'textContent',\n usedText = false;\n switch(entity._) {\n case 'messageEntityBold': {\n if(!options.noTextFormat) {\n if(options.wrappingDraft) {\n element = document.createElement('span');\n // element.style.fontWeight = 'bold';\n element.style.fontFamily = 'markup-bold';\n } else {\n element = document.createElement('strong');\n }\n }\n\n break;\n }\n\n case 'messageEntityItalic': {\n if(!options.noTextFormat) {\n if(options.wrappingDraft) {\n element = document.createElement('span');\n // element.style.fontStyle = 'italic';\n element.style.fontFamily = 'markup-italic';\n } else {\n element = document.createElement('em');\n }\n }\n\n break;\n }\n\n case 'messageEntityStrike': {\n if(options.wrappingDraft) {\n element = document.createElement('span');\n // const styleName = IS_SAFARI ? 'text-decoration' : 'text-decoration-line';\n // element.style.cssText = `${styleName}: line-through;`;\n element.style.fontFamily = 'markup-strikethrough';\n } else/* if(!options.noTextFormat) */ {\n element = document.createElement('del');\n }\n\n break;\n }\n\n case 'messageEntityUnderline': {\n if(options.wrappingDraft) {\n element = document.createElement('span');\n // const styleName = IS_SAFARI ? 'text-decoration' : 'text-decoration-line';\n // element.style.cssText = `${styleName}: underline;`;\n element.style.fontFamily = 'markup-underline';\n } else if(!options.noTextFormat) {\n element = document.createElement('u');\n }\n\n break;\n }\n\n case 'messageEntityPre':\n case 'messageEntityCode': {\n if(options.wrappingDraft) {\n element = document.createElement('span');\n // element.style.fontFamily = 'var(--font-monospace)';\n element.style.fontFamily = 'markup-monospace';\n } else if(!options.noTextFormat) {\n element = document.createElement('code');\n }\n\n break;\n }\n\n // case 'messageEntityPre': {\n // if(options.wrappingDraft) {\n // element = document.createElement('span');\n // element.style.fontFamily = 'var(--font-monospace)';\n // } else if(!options.noTextFormat) {\n // element = document.createElement('pre');\n // const inner = document.createElement('code');\n // if(entity.language) {\n // inner.className = 'language-' + entity.language;\n // inner.textContent = entityText;\n // usedText = true;\n // }\n // }\n\n // break;\n // }\n\n case 'messageEntityHighlight': {\n element = document.createElement('i');\n element.className = 'text-highlight';\n break;\n }\n\n case 'messageEntityBotCommand': {\n // if(!(options.noLinks || options.noCommands || contextExternal)/* && !entity.unsafe */) {\n if(!options.noLinks && passEntities[entity._]) {\n let command = fullEntityText.slice(1);\n let bot: string | boolean;\n let atPos: number;\n if((atPos = command.indexOf('@')) !== -1) {\n bot = command.slice(atPos + 1);\n command = command.slice(0, atPos);\n } else {\n bot = options.fromBot;\n }\n\n element = document.createElement('a');\n (element as HTMLAnchorElement).href = encodeEntities('tg://bot_command?command=' + encodeURIComponent(command) + (bot ? '&bot=' + encodeURIComponent(bot) : ''));\n if(!contextExternal) {\n element.setAttribute('onclick', 'execBotCommand(this)');\n }\n }\n\n break;\n }\n\n case 'messageEntityCustomEmoji': {\n if(!IS_CUSTOM_EMOJI_SUPPORTED) {\n break;\n }\n\n while(nextEntity?._ === 'messageEntityEmoji' && nextEntity.offset < endOffset) {\n ++nasty.i;\n nasty.lastEntity = nextEntity;\n nasty.usedLength += nextEntity.length;\n nextEntity = entities[nasty.i + 1];\n }\n\n const customEmojiElement = element = CustomEmojiElement.create(entity.document_id);\n const {docId} = customEmojiElement;\n let set = customEmojis.get(docId);\n if(!set) customEmojis.set(docId, set = new Set());\n set.add(customEmojiElement);\n customEmojiElement.dataset.stickerEmoji = fullEntityText;\n\n if(options.wrappingDraft) {\n element = document.createElement('img');\n (element as HTMLImageElement).alt = fullEntityText;\n for(const i in customEmojiElement.dataset) {\n element.dataset[i] = customEmojiElement.dataset[i];\n }\n (element as any).customEmojiElement = customEmojiElement;\n customEmojiElement.placeholder = element as HTMLImageElement;\n element.classList.add('custom-emoji-placeholder');\n (element as HTMLImageElement).src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAAtJREFUGFdjYAACAAAFAAGq1chRAAAAAElFTkSuQmCC';\n property = 'alt';\n break;\n }\n\n if(options.isSelectable) {\n // const s = document.createElement('span');\n // s.append(fullEntityText);\n // element.append(s);\n // element.textContent = fullEntityText;\n // element.textContent = 'a';\n // element.contentEditable = 'false';\n\n // const x = f();\n // x.style.display = 'inline-block';\n // x.contentEditable = 'false';\n // (lastElement || fragment).append(BOM);\n // (lastElement || fragment).append(x);\n\n element = wrapSomething(element, !!options.customEmojiRenderer);\n\n // const a = element;\n // element = document.createElement('span');\n // element.append(BOM, a, BOM);\n // element.contentEditable = 'false';\n }\n\n property = 'alt';\n break;\n }\n\n case 'messageEntityEmoji': {\n let isSupported = IS_EMOJI_SUPPORTED;\n if(isSupported) {\n for(const version in EmojiVersions) {\n if(version) {\n const emojiData = EmojiVersions[version as EMOJI_VERSION];\n if(emojiData.hasOwnProperty(entity.unicode) && !EMOJI_VERSIONS_SUPPORTED[version as EMOJI_VERSION]) {\n isSupported = false;\n break;\n }\n }\n }\n }\n\n // if(!(options.wrappingDraft && isSupported)) { // * fix safari emoji\n if(!isSupported) { // no wrapping needed\n // if(isSupported) { // ! contenteditable=\"false\" нужен для поля ввода, иначе там будет меняться шрифт в Safari, или же рендерить смайлик напрямую, без контейнера\n // insertPart(entity, '<span class=\"emoji\">', '</span>');\n // } else {\n element = document.createElement('img');\n (element as HTMLImageElement).src = `assets/img/emoji/${entity.unicode}.png`;\n property = 'alt';\n element.className = 'emoji';\n\n // if(options.isSelectable) {\n // usedText = true;\n // (element as HTMLImageElement).alt = partText;\n // element = wrapSomething(element);\n // }\n\n // const a = element;\n // a.contentEditable = 'false';\n // element = document.createElement('span');\n // element.append(a);\n // element.contentEditable = 'false';\n // }\n // } else if(options.mustWrapEmoji) {\n } else if(!options.wrappingDraft) {\n element = document.createElement('span');\n element.className = 'emoji';\n }/* else if(!IS_SAFARI) {\n insertPart(entity, '<span class=\"emoji\" contenteditable=\"false\">', '</span>');\n } */\n /* if(!isSupported) {\n insertPart(entity, `<img src=\"assets/img/emoji/${entity.unicode}.png\" alt=\"`, `\" class=\"emoji\">`);\n } */\n\n break;\n }\n\n case 'messageEntityCaret': {\n element = document.createElement('span');\n element.className = 'composer-sel';\n break;\n }\n\n case 'messageEntityLinebreak': {\n if(options.wrappingDraft && IS_FIREFOX) {\n element = document.createElement('br');\n }\n // if(options.noLinebreaks) {\n // insertPart(entity, ' ');\n // } else {\n // insertPart(entity, '<br/>');\n // }\n\n break;\n }\n\n case 'messageEntityUrl':\n case 'messageEntityTextUrl': {\n if(!(options.noLinks && !passEntities[entity._])) {\n // let inner: string;\n let url: string = (entity as MessageEntity.messageEntityTextUrl).url || fullEntityText;\n let masked = false;\n let onclick: string;\n\n const wrapped = wrapUrl(url, true);\n url = wrapped.url;\n onclick = wrapped.onclick;\n\n if(entity._ === 'messageEntityTextUrl') {\n if(nextEntity?._ === 'messageEntityUrl' &&\n nextEntity.length === entity.length &&\n nextEntity.offset === entity.offset) {\n nasty.lastEntity = nextEntity;\n ++nasty.i;\n }\n\n if(url !== fullEntityText) {\n masked = true;\n }\n } else {\n // inner = encodeEntities(replaceUrlEncodings(entityText));\n }\n\n const currentContext = !!onclick;\n if(!onclick && masked && !currentContext) {\n onclick = 'showMaskedAlert';\n }\n\n if(options.wrappingDraft) {\n onclick = undefined;\n }\n\n const href = (currentContext || typeof electronHelpers === 'undefined') ?\n url :\n `javascript:electronHelpers.openExternal('${url}');`;\n\n element = document.createElement('a');\n element.className = 'anchor-url';\n (element as HTMLAnchorElement).href = href;\n\n if(!(currentContext || typeof electronHelpers !== 'undefined')) {\n setBlankToAnchor(element as HTMLAnchorElement);\n }\n\n if(onclick) {\n element.setAttribute('onclick', onclick + '(this)');\n }\n }\n\n break;\n }\n\n case 'messageEntityEmail': {\n if(!options.noLinks) {\n element = document.createElement('a');\n (element as HTMLAnchorElement).href = encodeEntities('mailto:' + fullEntityText);\n setBlankToAnchor(element as HTMLAnchorElement);\n }\n\n break;\n }\n\n case 'messageEntityHashtag': {\n const contextUrl = !options.noLinks && SITE_HASHTAGS[contextSite];\n if(contextUrl) {\n const hashtag = fullEntityText.slice(1);\n element = document.createElement('a');\n element.className = 'anchor-hashtag';\n (element as HTMLAnchorElement).href = contextUrl.replace('{1}', encodeURIComponent(hashtag));\n if(contextExternal) {\n setBlankToAnchor(element as HTMLAnchorElement);\n } else {\n element.setAttribute('onclick', 'searchByHashtag(this)');\n }\n }\n\n break;\n }\n\n case 'messageEntityMentionName': {\n if(!(options.noLinks && !passEntities[entity._])) {\n element = document.createElement('a');\n (element as HTMLAnchorElement).href = buildURLHash('' + entity.user_id);\n element.className = 'follow';\n element.dataset.follow = '' + entity.user_id;\n }\n\n break;\n }\n\n case 'messageEntityMention': {\n // const contextUrl = !options.noLinks && siteMentions[contextSite];\n if(!options.noLinks) {\n const username = fullEntityText.slice(1);\n\n element = wrapTelegramUrlToAnchor('t.me/' + username);\n element.className = 'mention';\n\n // insertPart(entity, `<a class=\"mention\" href=\"${contextUrl.replace('{1}', encodeURIComponent(username))}\"${contextExternal ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : ''}>`, '</a>');\n }\n\n break;\n }\n\n case 'messageEntitySpoiler': {\n if(options.noTextFormat) {\n const encoded = encodeSpoiler(nasty.text, entity);\n nasty.text = encoded.text;\n partText = encoded.entityText;\n if(endPartOffset !== endOffset) {\n nasty.usedLength += endOffset - endPartOffset;\n }\n let n: MessageEntity;\n for(; n = entities[nasty.i + 1], n && n.offset < endOffset;) {\n // nasty.usedLength += n.length;\n ++nasty.i;\n nasty.lastEntity = n;\n nextEntity = entities[nasty.i + 1];\n }\n } else if(options.wrappingDraft) {\n element = document.createElement('span');\n // element.style.fontFamily = 'spoiler';\n element.style.fontFamily = 'markup-spoiler';\n } else {\n const container = document.createElement('span');\n container.className = 'spoiler';\n element = document.createElement('span');\n element.className = 'spoiler-text';\n element.textContent = partText;\n usedText = true;\n container.append(element);\n fragment.append(container);\n\n container[`on${CLICK_EVENT_NAME}`] = (window as any).onSpoilerClick;\n }\n\n break;\n }\n\n case 'messageEntityTimestamp': {\n if(!options.maxMediaTimestamp || entity.time > options.maxMediaTimestamp) {\n break;\n }\n\n element = document.createElement('a');\n element.classList.add('timestamp');\n element.dataset.timestamp = '' + entity.time;\n (element as HTMLAnchorElement).href = '#';\n element.setAttribute('onclick', 'setMediaTimestamp(this)');\n\n if(options.maxMediaTimestamp === Infinity) {\n element.classList.add('is-disabled');\n }\n\n break;\n }\n }\n\n if(!usedText && partText) {\n if(element) {\n // @ts-ignore\n element[property] = partText;\n } else {\n (element || fragment).append(partText);\n }\n }\n\n if(element && !element.parentNode) {\n (lastElement || fragment).append(element);\n }\n\n while(nextEntity && nextEntity.offset < endOffset) {\n ++nasty.i;\n\n (element || fragment).append(wrapRichText(nasty.text, {\n ...options,\n voodoo: true\n }));\n\n nextEntity = entities[nasty.i + 1];\n }\n\n // if(!element?.parentNode) {\n // (lastElement || fragment).append(element ?? partText);\n // }\n\n if(nasty.usedLength <= endOffset) {\n if(nasty.usedLength < endOffset) {\n (element || fragment).append(nasty.text.slice(nasty.usedLength, endOffset));\n nasty.usedLength = endOffset;\n }\n\n lastElement = fragment;\n nasty.lastEntity = undefined;\n } else if(entity.length > partText.length && element) {\n lastElement = element;\n } else {\n lastElement = fragment;\n }\n\n if(options.voodoo) {\n return fragment;\n }\n }\n\n if(nasty.lastEntity) {\n nasty.usedLength = nasty.lastEntity.offset + nasty.lastEntity.length;\n }\n\n if(nasty.usedLength < textLength) {\n (lastElement || fragment).append(nasty.text.slice(nasty.usedLength));\n }\n\n if((!options.wrappingDraft || options.customEmojiRenderer) && customEmojis.size) {\n let renderer = options.customEmojiRenderer;\n if(!renderer) {\n renderer = CustomEmojiRendererElement.create(options);\n fragment.prepend(renderer);\n }\n\n const loadPromise = renderer.add(customEmojis, options.lazyLoadQueue, options.wrappingDraft);\n options.loadPromises?.push(loadPromise);\n // recordPromise(loadPromise, 'render emojis: ' + docIds.length);\n }\n\n if(customWraps.size) {\n insertCustomFillers(customWraps);\n }\n\n return fragment;\n}\n\nexport const createCustomFiller = (notFiller?: boolean) => {\n const x = document.createElement('span');\n x.classList.add(notFiller ? 'input-filler2' : 'input-filler');\n x.textContent = BOM;\n return x;\n};\n\nexport function isCustomFillerNeededBySiblingNode(node: ChildNode) {\n if(\n // !node?.textContent ||\n // node.textContent.endsWith('\\n') ||\n node?.textContent !== BOM ||\n (node as HTMLElement)?.getAttribute?.('contenteditable') === 'false'\n ) {\n // if(!node || (node as HTMLElement).firstElementChild || node.textContent.endsWith('\\n')) {\n if(!node || node.textContent !== BOM || (node as HTMLElement).firstElementChild) {\n return 2;\n } else if(node.nodeType === node.ELEMENT_NODE) {\n return 1;\n }/* else if(node.nodeType === node.TEXT_NODE && !node.nodeValue) {\n (node as CharacterData).insertData(0, BOM);\n } */\n }\n\n return 0;\n}\n\nexport function insertCustomFillers(elements: Iterable<HTMLElement>) {\n const check = (element: HTMLElement, node: ChildNode, method: 'before' | 'after') => {\n const needed = isCustomFillerNeededBySiblingNode(node);\n if(needed === 2) {\n element[method](createCustomFiller());\n } else if(needed === 1) {\n node.appendChild(document.createTextNode(BOM));\n }\n };\n\n for(const element of elements) {\n const {previousSibling, nextSibling} = element;\n check(element, previousSibling, 'before');\n check(element, nextSibling, 'after');\n }\n}\n\n(window as any).wrapRichText = wrapRichText;\n","// just for the future\nexport default function buildURLHash(str: string) {\n return '#' + encodeURIComponent(str);\n}\n","import wrapUrl from './wrapUrl';\n\nexport default function wrapTelegramUrlToAnchor(url1: string) {\n const {url, onclick} = wrapUrl(url1);\n const element = document.createElement('a');\n (element as HTMLAnchorElement).href = url;\n if(onclick) {\n element.setAttribute('onclick', `${onclick}(this)`);\n }\n\n return element;\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport CAN_USE_TRANSFERABLES from '../../environment/canUseTransferables';\nimport EventListenerBase from '../../helpers/eventListenerBase';\n\nexport default class QueryableWorker extends EventListenerBase<{\n ready: () => void,\n frame: (reqId: number, frameNo: number, frame: Uint8ClampedArray | ImageBitmap) => void,\n loaded: (reqId: number, frameCount: number, fps: number) => void,\n error: (reqId: number, error: Error) => void,\n workerError: (error: ErrorEvent) => void\n}> {\n constructor(private worker: Worker) {\n super();\n\n this.worker.onerror = (error) => {\n try {\n this.dispatchEvent('workerError', error);\n this.cleanup();\n this.terminate();\n } catch(err) {\n\n }\n };\n\n this.worker.onmessage = (event) => {\n this.dispatchEvent(event.data.queryMethodListener, ...event.data.queryMethodArguments);\n };\n }\n\n public postMessage(message: any) {\n this.worker.postMessage(message);\n }\n\n public terminate() {\n this.worker.terminate();\n }\n\n public sendQuery(args: any[], transfer?: Transferable[]) {\n this.worker.postMessage({\n queryMethod: args.shift(),\n queryMethodArguments: args\n }, CAN_USE_TRANSFERABLES ? transfer: undefined);\n }\n}\n","const IS_WEB_ASSEMBLY_SUPPORTED = typeof(WebAssembly) !== 'undefined';\n\nexport default IS_WEB_ASSEMBLY_SUPPORTED;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport animationIntersector from '../../components/animationIntersector';\nimport {MOUNT_CLASS_TO} from '../../config/debug';\nimport pause from '../../helpers/schedulers/pause';\nimport {logger, LogTypes} from '../logger';\nimport RLottiePlayer, {RLottieOptions} from './rlottiePlayer';\nimport QueryableWorker from './queryableWorker';\nimport blobConstruct from '../../helpers/blob/blobConstruct';\nimport apiManagerProxy from '../mtproto/mtprotoworker';\nimport IS_WEB_ASSEMBLY_SUPPORTED from '../../environment/webAssemblySupport';\nimport makeError from '../../helpers/makeError';\nimport App from '../../config/app';\n\nexport type LottieAssetName = 'EmptyFolder' | 'Folders_1' | 'Folders_2' |\n 'TwoFactorSetupMonkeyClose' | 'TwoFactorSetupMonkeyCloseAndPeek' |\n 'TwoFactorSetupMonkeyCloseAndPeekToIdle' | 'TwoFactorSetupMonkeyIdle' |\n 'TwoFactorSetupMonkeyPeek' | 'TwoFactorSetupMonkeyTracking' |\n 'voice_outlined2' | 'voip_filled' | 'voice_mini' | 'jolly_roger' |\n 'Gift3' | 'Gift6' | 'Gift12';\n\nexport class LottieLoader {\n private loadPromise: Promise<void> = !IS_WEB_ASSEMBLY_SUPPORTED ? Promise.reject() : undefined;\n private loaded = false;\n\n private workersLimit = App.threads;\n private players: {[reqId: number]: RLottiePlayer} = {};\n private playersByCacheName: {[cacheName: string]: Set<RLottiePlayer>} = {};\n\n private workers: QueryableWorker[] = [];\n private curWorkerNum = 0;\n\n private log = logger('LOTTIE', LogTypes.Error);\n\n public getAnimation(element: HTMLElement) {\n for(const i in this.players) {\n if(this.players[i].el.includes(element)) {\n return this.players[i];\n }\n }\n\n return null;\n }\n\n public loadLottieWorkers() {\n if(this.loadPromise) {\n return this.loadPromise;\n }\n\n return this.loadPromise = new Promise((resolve, reject) => {\n let remain = this.workersLimit;\n for(let i = 0; i < this.workersLimit; ++i) {\n const worker = new Worker(new URL('./rlottie.worker.ts', import.meta.url));\n const queryableWorker = this.workers[i] = new QueryableWorker(worker);\n\n queryableWorker.addEventListener('ready', () => {\n this.log('worker #' + i + ' ready');\n\n queryableWorker.addEventListener('frame', this.onFrame);\n queryableWorker.addEventListener('loaded', this.onPlayerLoaded);\n queryableWorker.addEventListener('error', this.onPlayerError);\n\n --remain;\n if(!remain) {\n this.log('workers ready');\n resolve();\n this.loaded = true;\n }\n }, {once: true});\n\n queryableWorker.addEventListener('workerError', (error) => {\n reject('rlottie load error: ' + error.message);\n this.loaded = false;\n }, {once: true});\n }\n });\n }\n\n private makeAssetUrl(name: LottieAssetName) {\n return 'assets/tgs/' + name + '.json';\n }\n\n public loadAnimationAsAsset(params: Omit<RLottieOptions, 'animationData' | 'name'>, name: LottieAssetName) {\n // (params as RLottieOptions).name = name;\n return this.loadAnimationFromURL(params, this.makeAssetUrl(name));\n }\n\n public loadAnimationDataFromURL(url: string): Promise<Blob> {\n if(!IS_WEB_ASSEMBLY_SUPPORTED) {\n return this.loadPromise as any;\n }\n\n this.loadLottieWorkers();\n\n return fetch(url)\n .then((res) => {\n if(!res.headers || res.headers.get('content-type') === 'application/octet-stream') {\n return res.arrayBuffer()\n .then((data) => apiManagerProxy.invokeCrypto('gzipUncompress', data))\n .then((arr) => blobConstruct(arr as Uint8Array, ''));\n } else {\n return res.blob();\n }\n });\n /* .then((str) => {\n return new Promise<string>((resolve) => setTimeout(() => resolve(str), 2e3));\n }) */\n }\n\n public loadAnimationFromURLManually(name: LottieAssetName) {\n const url = this.makeAssetUrl(name);\n return this.loadAnimationDataFromURL(url).then((blob) => {\n return (params: Omit<RLottieOptions, 'animationData'>) => this.loadAnimationFromURLNext(blob, params, url);\n });\n }\n\n public loadAnimationFromURL(params: Omit<RLottieOptions, 'animationData'>, url: string) {\n return this.loadAnimationDataFromURL(url).then((blob) => {\n return this.loadAnimationFromURLNext(blob, params, url);\n });\n }\n\n public loadAnimationFromURLNext(blob: Blob, params: Omit<RLottieOptions, 'animationData'>, url: string) {\n const newParams = Object.assign(params, {animationData: blob, needUpscale: true});\n newParams.name ||= url;\n return this.loadAnimationWorker(newParams);\n }\n\n public waitForFirstFrame(player: RLottiePlayer) {\n return Promise.race([\n /* new Promise<void>((resolve) => {\n player.addEventListener('firstFrame', () => {\n setTimeout(() => resolve(), 1500);\n }, true);\n }) */\n new Promise<void>((resolve) => {\n player.addEventListener('firstFrame', resolve, {once: true});\n }),\n pause(2500)\n ]).then(() => player);\n }\n\n public async loadAnimationWorker(params: RLottieOptions): Promise<RLottiePlayer> {\n if(!IS_WEB_ASSEMBLY_SUPPORTED) {\n return this.loadPromise as any;\n }\n\n if(!this.loaded) {\n await this.loadLottieWorkers();\n }\n\n const {middleware, group = ''} = params;\n if(middleware && !middleware()) {\n throw makeError('MIDDLEWARE');\n }\n\n if(params.sync) {\n const cacheName = RLottiePlayer.CACHE.generateName(params.name, params.width, params.height, params.color, params.toneIndex);\n const players = this.playersByCacheName[cacheName];\n if(players?.size) {\n return Promise.resolve(players.entries().next().value[0]);\n }\n }\n\n const containers = Array.isArray(params.container) ? params.container : [params.container];\n if(!params.width || !params.height) {\n params.width = parseInt(containers[0].style.width);\n params.height = parseInt(containers[0].style.height);\n }\n\n if(!params.width || !params.height) {\n throw new Error('No size for sticker!');\n }\n\n params.group = group;\n\n const player = this.initPlayer(containers, params);\n\n animationIntersector.addAnimation({\n animation: player,\n group,\n controlled: middleware,\n liteModeKey: params.liteModeKey\n });\n\n return player;\n }\n\n private onPlayerLoaded = (reqId: number, frameCount: number, fps: number) => {\n const player = this.players[reqId];\n if(!player) {\n this.log.warn('onPlayerLoaded on destroyed player:', reqId, frameCount);\n return;\n }\n\n this.log.debug('onPlayerLoaded');\n player.onLoad(frameCount, fps);\n };\n\n private onFrame = (reqId: number, frameNo: number, frame: Uint8ClampedArray | ImageBitmap) => {\n const player = this.players[reqId];\n if(!player) {\n this.log.warn('onFrame on destroyed player:', reqId, frameNo);\n return;\n }\n\n if(player.clamped !== undefined && frame instanceof Uint8ClampedArray) {\n player.clamped = frame;\n }\n\n player.renderFrame(frame, frameNo);\n };\n\n private onPlayerError = (reqId: number, error: Error) => {\n const player = this.players[reqId];\n if(!player) {\n return;\n }\n\n // ! will need refactoring later, this is not the best way to remove the animation\n const animations = animationIntersector.getAnimations(player.el[0]);\n animations.forEach((animation) => {\n animationIntersector.removeAnimation(animation);\n });\n };\n\n public onDestroy(reqId: number) {\n delete this.players[reqId];\n }\n\n public destroyWorkers() {\n if(!IS_WEB_ASSEMBLY_SUPPORTED) {\n return;\n }\n\n this.workers.forEach((worker, idx) => {\n worker.terminate();\n this.log('worker #' + idx + ' terminated');\n });\n\n this.log('workers destroyed');\n this.workers.length = 0;\n this.curWorkerNum = 0;\n this.loaded = false;\n this.loadPromise = undefined;\n }\n\n private initPlayer(el: RLottiePlayer['el'], options: RLottieOptions) {\n const player = new RLottiePlayer({\n el,\n worker: this.workers[this.curWorkerNum++],\n options\n });\n\n const {reqId, cacheName} = player;\n this.players[reqId] = player;\n\n const playersByCacheName = cacheName ? this.playersByCacheName[cacheName] ??= new Set() : undefined;\n if(cacheName) {\n playersByCacheName.add(player);\n }\n\n if(this.curWorkerNum >= this.workers.length) {\n this.curWorkerNum = 0;\n }\n\n player.addEventListener('destroy', () => {\n this.onDestroy(reqId);\n if(playersByCacheName.delete(player) && !playersByCacheName.size) {\n delete this.playersByCacheName[cacheName];\n }\n });\n\n player.loadFromData(options.animationData);\n\n return player;\n }\n}\n\nconst lottieLoader = new LottieLoader();\nMOUNT_CLASS_TO.lottieLoader = lottieLoader;\nexport default lottieLoader;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport type {AnimationItemGroup, AnimationItemWrapper} from '../../components/animationIntersector';\nimport type {Middleware} from '../../helpers/middleware';\nimport type {LiteModeKey} from '../../helpers/liteMode';\nimport CAN_USE_TRANSFERABLES from '../../environment/canUseTransferables';\nimport IS_APPLE_MX from '../../environment/appleMx';\nimport {IS_ANDROID, IS_APPLE_MOBILE, IS_APPLE, IS_SAFARI} from '../../environment/userAgent';\nimport EventListenerBase from '../../helpers/eventListenerBase';\nimport mediaSizes from '../../helpers/mediaSizes';\nimport clamp from '../../helpers/number/clamp';\nimport QueryableWorker from './queryableWorker';\nimport IS_IMAGE_BITMAP_SUPPORTED from '../../environment/imageBitmapSupport';\nimport framesCache, {FramesCache, FramesCacheItem} from '../../helpers/framesCache';\n\nexport type RLottieOptions = {\n container: HTMLElement | HTMLElement[],\n middleware?: Middleware,\n canvas?: HTMLCanvasElement,\n autoplay?: boolean,\n animationData: Blob,\n loop?: RLottiePlayer['loop'],\n width?: number,\n height?: number,\n group?: AnimationItemGroup,\n noCache?: boolean,\n needUpscale?: boolean,\n skipRatio?: number,\n initFrame?: number, // index\n color?: RLottieColor,\n inverseColor?: RLottieColor,\n name?: string,\n skipFirstFrameRendering?: boolean,\n toneIndex?: number,\n sync?: boolean,\n liteModeKey?: LiteModeKey\n};\n\nexport type RLottieColor = [number, number, number];\n\nexport function getLottiePixelRatio(width: number, height: number, needUpscale?: boolean) {\n let pixelRatio = clamp(window.devicePixelRatio, 1, 2);\n if(pixelRatio > 1 && !needUpscale) {\n if(width > 90 && height > 90) {\n if(!IS_APPLE && mediaSizes.isMobile) {\n pixelRatio = 1;\n }\n } else if((width > 60 && height > 60) || IS_ANDROID) {\n pixelRatio = Math.max(1.5, pixelRatio - 1.5);\n }\n }\n\n return pixelRatio;\n}\n\nexport default class RLottiePlayer extends EventListenerBase<{\n enterFrame: (frameNo: number) => void,\n ready: () => void,\n firstFrame: () => void,\n cached: () => void,\n destroy: () => void\n}> implements AnimationItemWrapper {\n public static CACHE = framesCache;\n private static reqId = 0;\n\n public reqId = 0;\n public curFrame: number;\n private frameCount: number;\n private fps: number;\n private skipDelta: number;\n public name: string;\n public cacheName: string;\n private toneIndex: number;\n\n private worker: QueryableWorker;\n\n private width = 0;\n private height = 0;\n\n public el: HTMLElement[];\n public canvas: HTMLCanvasElement[];\n private contexts: CanvasRenderingContext2D[];\n\n public paused = true;\n // public paused = false;\n public direction = 1;\n private speed = 1;\n public autoplay = true;\n public _autoplay: boolean; // ! will be used to store original value for settings.stickers.loop\n public loop: number | boolean = true;\n public _loop: RLottiePlayer['loop']; // ! will be used to store original value for settings.stickers.loop\n public group: AnimationItemGroup = '';\n public liteModeKey: LiteModeKey;\n\n private frInterval: number;\n private frThen: number;\n private rafId: number;\n\n // private caching = false;\n // private removed = false;\n\n private cache: FramesCacheItem;\n private imageData: ImageData;\n public clamped: Uint8ClampedArray;\n private cachingDelta = 0;\n\n private initFrame: number;\n private color: RLottieColor;\n private inverseColor: RLottieColor;\n\n public minFrame: number;\n public maxFrame: number;\n\n private playedTimes = 0;\n\n private currentMethod: RLottiePlayer['mainLoopForwards'] | RLottiePlayer['mainLoopBackwards'];\n private frameListener: (currentFrame: number) => void;\n private skipFirstFrameRendering: boolean;\n private playToFrameOnFrameCallback: (frameNo: number) => void;\n\n public overrideRender: (frame: ImageData | HTMLCanvasElement | ImageBitmap) => void;\n private renderedFirstFrame: boolean;\n\n private raw: boolean;\n\n constructor({el, worker, options}: {\n el: RLottiePlayer['el'],\n worker: QueryableWorker,\n options: RLottieOptions\n }) {\n super(true);\n\n this.reqId = ++RLottiePlayer['reqId'];\n this.el = el;\n this.worker = worker;\n\n for(const i in options) {\n if(this.hasOwnProperty(i)) {\n // @ts-ignore\n this[i] = options[i];\n }\n }\n\n this._loop = this.loop;\n this._autoplay = this.autoplay;\n\n // ! :(\n this.initFrame = options.initFrame;\n this.color = options.color;\n this.inverseColor = options.inverseColor;\n this.name = options.name;\n this.skipFirstFrameRendering = options.skipFirstFrameRendering;\n this.toneIndex = options.toneIndex;\n this.raw = this.color !== undefined;\n this.liteModeKey = options.liteModeKey;\n\n if(this.name) {\n this.cacheName = RLottiePlayer.CACHE.generateName(this.name, this.width, this.height, this.color, this.toneIndex);\n }\n\n // * Skip ratio (30fps)\n let skipRatio: number;\n if(options.skipRatio !== undefined) skipRatio = options.skipRatio;\n else if((IS_ANDROID || IS_APPLE_MOBILE || (IS_APPLE && !IS_SAFARI && !IS_APPLE_MX)) && this.width < 100 && this.height < 100 && !options.needUpscale) {\n skipRatio = 0.5;\n }\n\n this.skipDelta = skipRatio !== undefined ? 1 / skipRatio | 0 : 1;\n\n // options.needUpscale = true;\n\n // * Pixel ratio\n const pixelRatio = getLottiePixelRatio(this.width, this.height, options.needUpscale);\n\n this.width = Math.round(this.width * pixelRatio);\n this.height = Math.round(this.height * pixelRatio);\n\n // options.noCache = true;\n\n // * Cache frames params\n if(!options.noCache/* && false */) {\n // проверка на размер уже после скейлинга, сделано для попапа и сайдбара, где стикеры 80х80 и 68х68, туда нужно 75%\n if(IS_APPLE && this.width > 100 && this.height > 100) {\n this.cachingDelta = 2; // 2 // 50%\n } else if(this.width < 100 && this.height < 100) {\n this.cachingDelta = Infinity; // 100%\n } else {\n this.cachingDelta = 4; // 75%\n }\n }\n\n // this.cachingDelta = Infinity;\n // this.cachingDelta = 0;\n // if(isApple) {\n // this.cachingDelta = 0; //2 // 50%\n // }\n\n if(!this.canvas) {\n this.canvas = this.el.map(() => {\n const canvas = document.createElement('canvas');\n canvas.classList.add('rlottie');\n canvas.width = this.width;\n canvas.height = this.height;\n canvas.dpr = pixelRatio;\n return canvas;\n });\n }\n\n this.contexts = this.canvas.map((canvas) => canvas.getContext('2d'));\n\n if(!IS_IMAGE_BITMAP_SUPPORTED || this.raw) {\n this.imageData = new ImageData(this.width, this.height);\n\n if(CAN_USE_TRANSFERABLES) {\n this.clamped = new Uint8ClampedArray(this.width * this.height * 4);\n }\n }\n\n if(this.name) {\n this.cache = RLottiePlayer.CACHE.getCache(this.cacheName);\n } else {\n this.cache = FramesCache.createCache();\n }\n }\n\n public clearCache() {\n if(this.cachingDelta === Infinity) {\n return;\n }\n\n if(this.cacheName && this.cache.counter > 1) { // skip clearing because same sticker can be still visible\n return;\n }\n\n this.cache.clearCache();\n }\n\n public sendQuery(args: any[], transfer?: Transferable[]) {\n this.worker.sendQuery([args.shift(), this.reqId, ...args], transfer);\n }\n\n public loadFromData(data: RLottieOptions['animationData']) {\n this.sendQuery(['loadFromData', data, this.width, this.height, this.toneIndex, this.color !== undefined/* , this.canvas.transferControlToOffscreen() */]);\n }\n\n public play() {\n if(!this.paused) {\n return;\n }\n\n this.paused = false;\n this.setMainLoop();\n }\n\n public pause(clearPendingRAF = true) {\n if(this.paused) {\n return;\n }\n\n this.paused = true;\n if(clearPendingRAF) {\n clearTimeout(this.rafId);\n this.rafId = undefined;\n }\n // window.cancelAnimationFrame(this.rafId);\n }\n\n private resetCurrentFrame() {\n return this.curFrame = this.initFrame ?? (this.direction === 1 ? this.minFrame : this.maxFrame);\n }\n\n public stop(renderFirstFrame = true) {\n this.pause();\n\n const curFrame = this.resetCurrentFrame();\n if(renderFirstFrame) {\n this.requestFrame(curFrame);\n // this.sendQuery('renderFrame', this.curFrame);\n }\n }\n\n public restart() {\n this.stop(false);\n this.play();\n }\n\n public playOrRestart() {\n if(!this.paused) {\n return;\n }\n\n if(this.curFrame === this.maxFrame) {\n this.restart();\n } else {\n this.play();\n }\n }\n\n public setSpeed(speed: number) {\n if(this.speed === speed) {\n return;\n }\n\n this.speed = speed;\n\n if(!this.paused) {\n this.setMainLoop();\n }\n }\n\n public setDirection(direction: number) {\n if(this.direction === direction) {\n return;\n }\n\n this.direction = direction;\n\n if(!this.paused) {\n this.setMainLoop();\n }\n }\n\n public remove() {\n this.pause();\n this.sendQuery(['destroy']);\n if(this.cacheName) RLottiePlayer.CACHE.releaseCache(this.cacheName);\n this.dispatchEvent('destroy');\n this.cleanup();\n }\n\n private applyColor(frame: Uint8ClampedArray) {\n const [r, g, b] = this.color;\n for(let i = 0, length = frame.length; i < length; i += 4) {\n if(frame[i + 3] !== 0) {\n frame[i] = r;\n frame[i + 1] = g;\n frame[i + 2] = b;\n }\n }\n }\n\n private applyInversing(frame: Uint8ClampedArray) {\n const [r, g, b] = this.inverseColor;\n for(let i = 0, length = frame.length; i < length; i += 4) {\n if(frame[i + 3] === 0) {\n frame[i] = r;\n frame[i + 1] = g;\n frame[i + 2] = b;\n frame[i + 3] = 255;\n } else {\n frame[i + 3] = 0;\n }\n }\n }\n\n public renderFrame2(frame: Uint8ClampedArray | HTMLCanvasElement | ImageBitmap, frameNo: number) {\n /* this.setListenerResult('enterFrame', frameNo);\n return; */\n\n try {\n if(frame instanceof Uint8ClampedArray) {\n if(this.color) {\n this.applyColor(frame);\n }\n\n if(this.inverseColor) {\n this.applyInversing(frame);\n }\n\n this.imageData.data.set(frame);\n }\n\n // this.context.putImageData(new ImageData(frame, this.width, this.height), 0, 0);\n this.contexts.forEach((context, idx) => {\n let cachedSource: HTMLCanvasElement | ImageBitmap = this.cache.framesNew.get(frameNo);\n if(!(frame instanceof Uint8ClampedArray)) {\n cachedSource = frame;\n } else if(idx > 0) {\n cachedSource = this.canvas[0];\n }\n\n if(!cachedSource) {\n // console.log('drawing from data');\n const c = document.createElement('canvas');\n c.width = context.canvas.width;\n c.height = context.canvas.height;\n c.getContext('2d').putImageData(this.imageData, 0, 0);\n this.cache.framesNew.set(frameNo, c);\n cachedSource = c;\n }\n\n if(this.overrideRender && this.renderedFirstFrame) {\n this.overrideRender(cachedSource || this.imageData);\n } else if(cachedSource) {\n // console.log('drawing from canvas');\n context.clearRect(0, 0, cachedSource.width, cachedSource.height);\n context.drawImage(cachedSource, 0, 0);\n } else {\n context.putImageData(this.imageData, 0, 0);\n }\n\n if(!this.renderedFirstFrame) {\n this.renderedFirstFrame = true;\n }\n });\n\n this.dispatchEvent('enterFrame', frameNo);\n } catch(err) {\n console.error('RLottiePlayer renderFrame error:', err/* , frame */, this.width, this.height);\n this.autoplay = false;\n this.pause();\n }\n }\n\n public renderFrame(frame: Parameters<RLottiePlayer['renderFrame2']>[0], frameNo: number) {\n const canCacheFrame = this.cachingDelta && (frameNo % this.cachingDelta || !frameNo);\n if(canCacheFrame) {\n if(frame instanceof Uint8ClampedArray && !this.cache.frames.has(frameNo)) {\n this.cache.frames.set(frameNo, new Uint8ClampedArray(frame));// frame;\n } else if(IS_IMAGE_BITMAP_SUPPORTED && frame instanceof ImageBitmap && !this.cache.framesNew.has(frameNo)) {\n this.cache.framesNew.set(frameNo, frame);\n }\n }\n\n /* if(!this.listenerResults.hasOwnProperty('cached')) {\n this.setListenerResult('enterFrame', frameNo);\n if(frameNo === (this.frameCount - 1)) {\n this.setListenerResult('cached');\n }\n\n return;\n } */\n\n if(this.frInterval) {\n const now = Date.now(), delta = now - this.frThen;\n\n if(delta < 0) {\n const timeout = this.frInterval > -delta ? -delta % this.frInterval : this.frInterval;\n if(this.rafId) clearTimeout(this.rafId);\n this.rafId = window.setTimeout(() => {\n this.renderFrame2(frame, frameNo);\n }, timeout);\n // await new Promise((resolve) => setTimeout(resolve, -delta % this.frInterval));\n return;\n }\n }\n\n this.renderFrame2(frame, frameNo);\n }\n\n public requestFrame(frameNo: number) {\n const frame = this.cache.frames.get(frameNo);\n const frameNew = this.cache.framesNew.get(frameNo);\n if(frameNew) {\n this.renderFrame(frameNew, frameNo);\n } else if(frame) {\n this.renderFrame(frame, frameNo);\n } else {\n if(this.clamped && !this.clamped.length) { // fix detached\n this.clamped = new Uint8ClampedArray(this.width * this.height * 4);\n }\n\n this.sendQuery(['renderFrame', frameNo], this.clamped ? [this.clamped.buffer] : undefined);\n }\n }\n\n private onLap() {\n if(++this.playedTimes === this.loop) {\n this.loop = false;\n }\n\n if(!this.loop) {\n this.pause(false);\n return false;\n }\n\n return true;\n }\n\n private mainLoopForwards() {\n const {skipDelta, maxFrame} = this;\n const frame = (this.curFrame + skipDelta) > maxFrame ? this.curFrame = (this.loop ? this.minFrame : this.maxFrame) : this.curFrame += skipDelta;\n // console.log('mainLoopForwards', this.curFrame, skipDelta, frame);\n\n this.requestFrame(frame);\n if((frame + skipDelta) > maxFrame) {\n return this.onLap();\n }\n\n return true;\n }\n\n private mainLoopBackwards() {\n const {skipDelta, minFrame} = this;\n const frame = (this.curFrame - skipDelta) < minFrame ? this.curFrame = (this.loop ? this.maxFrame : this.minFrame) : this.curFrame -= skipDelta;\n // console.log('mainLoopBackwards', this.curFrame, skipDelta, frame);\n\n this.requestFrame(frame);\n if((frame - skipDelta) < minFrame) {\n return this.onLap();\n }\n\n return true;\n }\n\n public setMainLoop() {\n // window.cancelAnimationFrame(this.rafId);\n clearTimeout(this.rafId);\n this.rafId = undefined;\n\n this.frInterval = 1000 / this.fps / this.speed * this.skipDelta;\n this.frThen = Date.now() - this.frInterval;\n\n // console.trace('setMainLoop', this.frInterval, this.direction, this, JSON.stringify(this.listenerResults), this.listenerResults);\n\n const method = (this.direction === 1 ? this.mainLoopForwards : this.mainLoopBackwards).bind(this);\n this.currentMethod = method;\n // this.frameListener && this.removeListener('enterFrame', this.frameListener);\n\n // setTimeout(() => {\n // this.addListener('enterFrame', this.frameListener);\n // }, 0);\n\n if(this.frameListener) {\n const lastResult = this.listenerResults.enterFrame;\n if(lastResult !== undefined) {\n this.frameListener(this.curFrame);\n }\n }\n\n // this.mainLoop(method);\n // this.r(method);\n // method();\n }\n\n public playPart(options: {\n from: number,\n to: number,\n callback?: () => void\n }) {\n this.pause();\n\n const {from, to, callback} = options;\n this.curFrame = from - 1;\n\n return this.playToFrame({\n frame: to,\n direction: to > from ? 1 : -1,\n callback\n });\n }\n\n public playToFrame(options: {\n frame: number,\n speed?: number,\n direction?: number,\n callback?: () => void\n }) {\n this.pause();\n\n const {frame, speed, callback, direction} = options;\n this.setDirection(direction === undefined ? this.curFrame > frame ? -1 : 1 : direction);\n speed !== undefined && this.setSpeed(speed);\n\n const bounds = [this.curFrame, frame];\n if(this.direction === -1) bounds.reverse();\n\n this.loop = false;\n this.setMinMax(bounds[0], bounds[1]);\n\n if(this.playToFrameOnFrameCallback) {\n this.removeEventListener('enterFrame', this.playToFrameOnFrameCallback);\n }\n\n if(callback) {\n this.playToFrameOnFrameCallback = (frameNo: number) => {\n if(frameNo === frame) {\n this.removeEventListener('enterFrame', this.playToFrameOnFrameCallback);\n callback();\n }\n };\n\n this.addEventListener('enterFrame', this.playToFrameOnFrameCallback);\n }\n\n this.play();\n }\n\n public setColor(color: RLottieColor, renderIfPaused: boolean) {\n this.color = color;\n\n if(renderIfPaused && this.paused) {\n this.renderFrame2(this.imageData.data, this.curFrame);\n }\n }\n\n public setInverseColor(color: RLottieColor) {\n this.inverseColor = color;\n }\n\n private setMinMax(minFrame = 0, maxFrame = this.frameCount - 1) {\n this.minFrame = minFrame;\n this.maxFrame = maxFrame;\n }\n\n public async onLoad(frameCount: number, fps: number) {\n this.frameCount = frameCount;\n this.fps = fps;\n this.setMinMax();\n if(this.initFrame !== undefined) {\n this.initFrame = clamp(this.initFrame, this.minFrame, this.maxFrame);\n }\n\n const curFrame = this.resetCurrentFrame();\n\n // * Handle 30fps stickers if 30fps set\n if(this.fps < 60 && this.skipDelta !== 1) {\n const diff = 60 / fps;\n this.skipDelta = this.skipDelta / diff | 0;\n }\n\n this.frInterval = 1000 / this.fps / this.speed * this.skipDelta;\n this.frThen = Date.now() - this.frInterval;\n // this.sendQuery('renderFrame', 0);\n\n // Кешировать сразу не получится, рендер стикера (тайгер) занимает 519мс,\n // если рендерить 75% с получением каждого кадра из воркера, будет 475мс, т.е. при 100% было бы 593мс, потеря на передаче 84мс.\n\n /* console.time('cache' + this.reqId);\n for(let i = 0; i < frameCount; ++i) {\n //if(this.removed) return;\n\n if(i % 4) {\n await new Promise((resolve) => {\n delete this.listenerResults.enterFrame;\n this.addListener('enterFrame', resolve, true);\n this.requestFrame(i);\n });\n }\n }\n\n console.timeEnd('cache' + this.reqId); */\n // console.log('cached');\n /* this.el.innerHTML = '';\n this.el.append(this.canvas);\n return; */\n\n !this.skipFirstFrameRendering && this.requestFrame(curFrame);\n this.dispatchEvent('ready');\n this.addEventListener('enterFrame', () => {\n this.dispatchEvent('firstFrame');\n\n if(!this.canvas[0].parentNode && this.el && !this.overrideRender) {\n this.el.forEach((container, idx) => container.append(this.canvas[idx]));\n }\n\n // console.log('enterFrame firstFrame');\n\n // let lastTime = this.frThen;\n this.frameListener = () => {\n if(this.paused || !this.currentMethod) {\n return;\n }\n\n const time = Date.now();\n // console.log(`enterFrame handle${this.reqId}`, time, (time - lastTime), this.frInterval);\n /* if(Math.round(time - lastTime + this.frInterval * 0.25) < Math.round(this.frInterval)) {\n return;\n } */\n\n // lastTime = time;\n\n this.frThen = time + this.frInterval;\n const canContinue = this.currentMethod();\n if(!canContinue && !this.loop && this.autoplay) {\n this.autoplay = false;\n }\n };\n\n this.addEventListener('enterFrame', this.frameListener);\n // setInterval(this.frameListener, this.frInterval);\n\n // ! fix autoplaying since there will be no animationIntersector for it\n if(this.group === 'none' && this.autoplay) {\n this.play();\n }\n }, {once: true});\n }\n}\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport Page from './page';\nimport lottieLoader from '../lib/rlottie/lottieLoader';\nimport {horizontalMenu} from '../components/horizontalMenu';\nimport {MOUNT_CLASS_TO} from '../config/debug';\nimport fastSmoothScroll from '../helpers/fastSmoothScroll';\nimport whichChild from '../helpers/dom/whichChild';\n\nclass PagesManager {\n private pageId = -1;\n private page: Page;\n\n private selectTab: ReturnType<typeof horizontalMenu>;\n public pagesDiv: HTMLDivElement;\n public scrollableDiv: HTMLElement;\n\n constructor() {\n this.pagesDiv = document.getElementById('auth-pages') as HTMLDivElement;\n this.scrollableDiv = this.pagesDiv.querySelector('.scrollable') as HTMLElement;\n this.selectTab = horizontalMenu(null, this.scrollableDiv.querySelector('.tabs-container') as HTMLDivElement, null, () => {\n if(this.page?.onShown) {\n this.page.onShown();\n }\n });\n }\n\n public setPage(page: Page) {\n if(page.isAuthPage) {\n this.pagesDiv.style.display = '';\n\n const id = whichChild(page.pageEl);\n if(this.pageId === id) return;\n\n this.selectTab(id);\n\n if(this.pageId !== -1 && id > 1) {\n lottieLoader.loadLottieWorkers();\n }\n\n\n this.pageId = id;\n\n if(this.scrollableDiv) {\n fastSmoothScroll({\n container: this.scrollableDiv,\n element: this.scrollableDiv.firstElementChild as HTMLElement,\n position: 'start'\n });\n }\n } else {\n this.pagesDiv.style.display = 'none';\n page.pageEl.style.display = '';\n\n this.pageId = -1;\n }\n\n this.page = page;\n }\n}\n\nconst pagesManager = new PagesManager();\nMOUNT_CLASS_TO.pagesManager = pagesManager;\nexport default pagesManager;\n","/*\n * https://github.com/morethanwords/tweb\n * Copyright (C) 2019-2021 Eduard Kuzmenko\n * https://github.com/morethanwords/tweb/blob/master/LICENSE\n */\n\nimport pagesManager from './pagesManager';\n\nexport default class Page {\n public pageEl: HTMLDivElement;\n private installed = false;\n\n constructor(\n className: string,\n public isAuthPage: boolean,\n private onFirstMount?: (...args: any[]) => Promise<any> | void,\n private onMount?: (...args: any[]) => Promise<any> | void,\n public onShown?: () => void\n ) {\n this.pageEl = document.body.querySelector('.' + className) as HTMLDivElement;\n }\n\n public async mount(...args: any[]) {\n // this.pageEl.style.display = '';\n\n if(this.onMount) {\n const res = this.onMount(...args);\n if(res instanceof Promise) {\n await res;\n }\n }\n\n if(!this.installed) {\n if(this.onFirstMount) {\n try {\n const res = this.onFirstMount(...args);\n if(res instanceof Promise) {\n await res;\n }\n } catch(err) {\n console.error('PAGE MOUNT ERROR:', err);\n }\n }\n\n this.installed = true;\n }\n\n pagesManager.setPage(this);\n }\n}\n","// https://github.com/twitter/twemoji-parser/blob/master/src/lib/regex.js\n\nexport function encodeEmoji(emojiText: string) {\n const codepoints = toCodePoints(removeVS16s(emojiText)).join('-');\n return codepoints;\n}\n\nconst vs16RegExp = /\\uFE0F/g;\n// avoid using a string literal like '\\u200D' here because minifiers expand it inline\nconst zeroWidthJoiner = String.fromCharCode(0x200d);\n\nconst removeVS16s = (rawEmoji: string) => (rawEmoji.indexOf(zeroWidthJoiner) < 0 ? rawEmoji.replace(vs16RegExp, '') : rawEmoji);\n\nexport function toCodePoints(unicodeSurrogates: string): Array<string> {\n const points = [];\n let char = 0;\n let previous = 0;\n let i = 0;\n while(i < unicodeSurrogates.length) {\n char = unicodeSurrogates.charCodeAt(i++);\n if(previous) {\n points.push((0x10000 + ((previous - 0xd800) << 10) + (char - 0xdc00)).toString(16));\n previous = 0;\n } else if(char > 0xd800 && char <= 0xdbff) {\n previous = char;\n } else {\n points.push(char.toString(16));\n }\n }\n\n if(points.length && points[0].length === 2) {\n points[0] = '00' + points[0];\n }\n\n return points;\n}\n\nexport function getEmojiToneIndex(input: string) {\n const match = input.match(/[\\uDFFB-\\uDFFF]/);\n return match ? 5 - (57343 - match[0].charCodeAt(0)) : 0;\n}\n\nconst VIRTUAL_COUNTRIES_EMOJIS: Map<string, string> = new Map([\n ['FT', '🏴‍☠']\n]);\n\nexport function getCountryEmoji(iso2: string) {\n return VIRTUAL_COUNTRIES_EMOJIS.get(iso2) ??\n String.fromCharCode(55356, 56741 + iso2.charCodeAt(0), 55356, 56741 + iso2.charCodeAt(1));\n}\n\nexport function emojiFromCodePoints(codePoints: string) {\n return codePoints.split('-').reduce((prev, curr) => prev + String.fromCodePoint(parseInt(curr, 16)), '');\n}\n","!function(e,t){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define([],t):\"object\"==typeof exports?exports.Recorder=t():e.Recorder=t()}(\"undefined\"!=typeof self?self:this,(function(){return function(e){var t={};function o(i){if(t[i])return t[i].exports;var n=t[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,o),n.l=!0,n.exports}return o.m=e,o.c=t,o.d=function(e,t,i){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},o.r=function(e){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&\"object\"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(o.r(i),Object.defineProperty(i,\"default\",{enumerable:!0,value:e}),2&t&&\"string\"!=typeof e)for(var n in e)o.d(i,n,function(t){return e[t]}.bind(null,n));return i},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,\"a\",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p=\"\",o(o.s=0)}([function(e,t,o){\"use strict\";(function(t){var o=t.AudioContext||t.webkitAudioContext,i=function(e){if(!i.isRecordingSupported())throw new Error(\"Recording is not supported in this browser\");e||(e={}),this.state=\"inactive\",this.config=Object.assign({bufferLength:4096,encoderApplication:2049,encoderFrameSize:20,encoderPath:\"encoderWorker.min.js\",encoderSampleRate:48e3,maxFramesPerPage:40,mediaTrackConstraints:!0,monitorGain:0,numberOfChannels:1,recordingGain:1,resampleQuality:3,streamPages:!1,reuseWorker:!1,wavBitDepth:16},e),this.encodedSamplePosition=0};i.isRecordingSupported=function(){return o&&t.navigator&&t.navigator.mediaDevices&&t.navigator.mediaDevices.getUserMedia&&t.WebAssembly},i.prototype.clearStream=function(){this.stream&&(this.stream.getTracks?this.stream.getTracks().forEach((function(e){e.stop()})):this.stream.stop(),delete this.stream),this.audioContext&&this.closeAudioContext&&(this.audioContext.close(),delete this.audioContext)},i.prototype.encodeBuffers=function(e){if(\"recording\"===this.state){for(var t=[],o=0;o<e.numberOfChannels;o++)t[o]=e.getChannelData(o);this.encoder.postMessage({command:\"encode\",buffers:t})}},i.prototype.initAudioContext=function(e){return e&&e.context?(this.audioContext=e.context,this.closeAudioContext=!1):(this.audioContext=new o,this.closeAudioContext=!0),this.audioContext},i.prototype.initAudioGraph=function(){this.encodeBuffers=function(){delete this.encodeBuffers},this.scriptProcessorNode=this.audioContext.createScriptProcessor(this.config.bufferLength,this.config.numberOfChannels,this.config.numberOfChannels),this.scriptProcessorNode.connect(this.audioContext.destination),this.scriptProcessorNode.onaudioprocess=e=>{this.encodeBuffers(e.inputBuffer)},this.monitorGainNode=this.audioContext.createGain(),this.setMonitorGain(this.config.monitorGain),this.monitorGainNode.connect(this.audioContext.destination),this.recordingGainNode=this.audioContext.createGain(),this.setRecordingGain(this.config.recordingGain),this.recordingGainNode.connect(this.scriptProcessorNode)},i.prototype.initSourceNode=function(e){return e&&e.context?t.Promise.resolve(e):t.navigator.mediaDevices.getUserMedia({audio:this.config.mediaTrackConstraints}).then(e=>(this.stream=e,this.audioContext.createMediaStreamSource(e)))},i.prototype.loadWorker=function(){this.encoder||(this.encoder=new t.Worker(this.config.encoderPath))},i.prototype.initWorker=function(){var e=(this.config.streamPages?this.streamPage:this.storePage).bind(this);return this.recordedPages=[],this.totalLength=0,this.loadWorker(),new Promise((t,o)=>{var i=o=>{switch(o.data.message){case\"ready\":t();break;case\"page\":this.encodedSamplePosition=o.data.samplePosition,e(o.data.page);break;case\"done\":this.encoder.removeEventListener(\"message\",i),this.finish()}};this.encoder.addEventListener(\"message\",i),this.encoder.postMessage(Object.assign({command:\"init\",originalSampleRate:this.audioContext.sampleRate,wavSampleRate:this.audioContext.sampleRate},this.config))})},i.prototype.pause=function(e){if(\"recording\"===this.state){if(this.state=\"paused\",e&&this.config.streamPages){var t=this.encoder;return new Promise((e,o)=>{var i=o=>{\"flushed\"===o.data.message&&(t.removeEventListener(\"message\",i),this.onpause(),e())};t.addEventListener(\"message\",i),t.postMessage({command:\"flush\"})})}return this.onpause(),Promise.resolve()}},i.prototype.resume=function(){\"paused\"===this.state&&(this.state=\"recording\",this.onresume())},i.prototype.setRecordingGain=function(e){this.config.recordingGain=e,this.recordingGainNode&&this.audioContext&&this.recordingGainNode.gain.setTargetAtTime(e,this.audioContext.currentTime,.01)},i.prototype.setMonitorGain=function(e){this.config.monitorGain=e,this.monitorGainNode&&this.audioContext&&this.monitorGainNode.gain.setTargetAtTime(e,this.audioContext.currentTime,.01)},i.prototype.start=function(e){if(\"inactive\"===this.state)return this.initAudioContext(e),this.initAudioGraph(),this.encodedSamplePosition=0,this.initWorker().then(()=>this.initSourceNode(e)).then(e=>{this.sourceNode=e,this.state=\"recording\",this.onstart(),this.encoder.postMessage({command:\"getHeaderPages\"}),this.sourceNode.connect(this.monitorGainNode),this.sourceNode.connect(this.recordingGainNode)})},i.prototype.stop=function(){if(\"inactive\"!==this.state){this.state=\"inactive\",this.monitorGainNode.disconnect(),this.scriptProcessorNode.disconnect(),this.recordingGainNode.disconnect(),this.sourceNode.disconnect(),this.clearStream();var e=this.encoder;return new Promise(t=>{var o=i=>{\"done\"===i.data.message&&(e.removeEventListener(\"message\",o),t())};e.addEventListener(\"message\",o),e.postMessage({command:\"done\"}),this.config.reuseWorker||e.postMessage({command:\"close\"})})}return Promise.resolve()},i.prototype.destroyWorker=function(){\"inactive\"===this.state&&this.encoder&&(this.encoder.postMessage({command:\"close\"}),delete this.encoder)},i.prototype.storePage=function(e){this.recordedPages.push(e),this.totalLength+=e.length},i.prototype.streamPage=function(e){this.ondataavailable(e)},i.prototype.finish=function(){if(!this.config.streamPages){var e=new Uint8Array(this.totalLength);this.recordedPages.reduce((function(t,o){return e.set(o,t),t+o.length}),0),this.ondataavailable(e)}this.onstop(),this.config.reuseWorker||delete this.encoder},i.prototype.ondataavailable=function(){},i.prototype.onpause=function(){},i.prototype.onresume=function(){},i.prototype.onstart=function(){},i.prototype.onstop=function(){},e.exports=i}).call(this,o(1))},function(e,t){var o;o=function(){return this}();try{o=o||new Function(\"return this\")()}catch(e){\"object\"==typeof window&&(o=window)}e.exports=o}])}));","/**\n * https://github.com/gre/bezier-easing\n * BezierEasing - use bezier curve for transition easing function\n * by Gaëtan Renaudeau 2014 - 2015 MIT License\n */\n\n// These values are established by empiricism with tests (tradeoff: performance VS precision)\nvar NEWTON_ITERATIONS = 4;\nvar NEWTON_MIN_SLOPE = 0.001;\nvar SUBDIVISION_PRECISION = 0.0000001;\nvar SUBDIVISION_MAX_ITERATIONS = 10;\n\nvar kSplineTableSize = 11;\nvar kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);\n\nvar float32ArraySupported = typeof Float32Array === 'function';\n\nfunction A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }\nfunction B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }\nfunction C (aA1) { return 3.0 * aA1; }\n\n// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.\nfunction calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }\n\n// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.\nfunction getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }\n\nfunction binarySubdivide (aX, aA, aB, mX1, mX2) {\n var currentX, currentT, i = 0;\n do {\n currentT = aA + (aB - aA) / 2.0;\n currentX = calcBezier(currentT, mX1, mX2) - aX;\n if (currentX > 0.0) {\n aB = currentT;\n } else {\n aA = currentT;\n }\n } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);\n return currentT;\n}\n\nfunction newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {\n for (var i = 0; i < NEWTON_ITERATIONS; ++i) {\n var currentSlope = getSlope(aGuessT, mX1, mX2);\n if (currentSlope === 0.0) {\n return aGuessT;\n }\n var currentX = calcBezier(aGuessT, mX1, mX2) - aX;\n aGuessT -= currentX / currentSlope;\n }\n return aGuessT;\n}\n\nfunction LinearEasing (x) {\n return x;\n}\n\nmodule.exports = function bezier (mX1, mY1, mX2, mY2) {\n if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {\n throw new Error('bezier x values must be in [0, 1] range');\n }\n\n if (mX1 === mY1 && mX2 === mY2) {\n return LinearEasing;\n }\n\n // Precompute samples table\n var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);\n for (var i = 0; i < kSplineTableSize; ++i) {\n sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);\n }\n\n function getTForX (aX) {\n var intervalStart = 0.0;\n var currentSample = 1;\n var lastSample = kSplineTableSize - 1;\n\n for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {\n intervalStart += kSampleStepSize;\n }\n --currentSample;\n\n // Interpolate to provide an initial guess for t\n var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);\n var guessForT = intervalStart + dist * kSampleStepSize;\n\n var initialSlope = getSlope(guessForT, mX1, mX2);\n if (initialSlope >= NEWTON_MIN_SLOPE) {\n return newtonRaphsonIterate(aX, guessForT, mX1, mX2);\n } else if (initialSlope === 0.0) {\n return guessForT;\n } else {\n return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);\n }\n }\n\n return function BezierEasing (x) {\n // Because JavaScript number are imprecise, we should guarantee the extremes are right.\n if (x === 0 || x === 1) {\n return x;\n }\n return calcBezier(getTForX(x), mY1, mY2);\n };\n};\n"],"names":["animationIntersector","constructor","this","observer","IntersectionObserver","entries","entry","target","group","byGroups","intersectionLockedGroups","animation","find","p","el","isIntersecting","visible","add","checkAnimation","delete","_animation","clearCache","Set","overrideIdleGroups","byPlayer","Map","lockedGroups","onlyOnePlayableGroup","videosLocked","doc","type","checkAnimations2","idle","setOverrideIdleGroup","override","getAnimations","element","found","player","push","removeAnimation","HTMLVideoElement","remove","IS_SAFARI","setTimeout","src","load","length","unobserve","removeAnimationByPlayer","item","get","addAnimation","options","observeElement","controlled","liteModeKey","has","canvas","placeholder","HTMLElement","onClean","loop","observe","set","checkAnimations","blurred","destroy","imitateIntersection","undefined","groups","Object","keys","animations","paused","pause","autoplay","play","getOnlyOnePlayableGroup","setOnlyOnePlayableGroup","lockGroup","unlockGroup","refreshGroup","forEach","lockIntersectionGroup","unlockIntersectionGroup","toggleIntersectionGroup","lock","setAutoplay","changed","animationItem","dataset","stickerPlay","stickerLoop","setLoop","SHOULD_USE_SAFARI_FIX","navigator","userAgent","match","err","AppMediaPlaybackController","media","scheduled","mediaDetails","waitingMediaForLoad","waitingScheduledMediaForLoad","waitingDocumentsForLoad","playbackRates","voice","video","audio","seekBackward","details","playingMedia","currentTime","Math","max","seekOffset","seekForward","min","duration","seekTo","seekTime","onMediaDocumentLoad","managers","appDocsManager","getDoc","docId","supportsStreaming","handleSafariStreamable","cacheContext","thumbsStorage","getCacheContext","url","playbackRate","id","size","onPlay","e","peerId","mid","pip","message","getMessageByMedia","stop","setMedia","verify","listLoader","current","getCurrent","jumpLength","withOtherSide","previous","getPrevious","idx","findIndex","getNext","go","setTargets","dispatchEvent","getPlayingDetails","pauseMediaInOtherTabs","onPause","onEnded","isTrusted","lockedSwitchers","round","next","toggle","force","clean","s","isScheduled","storage","playingMediaType","playItem","searchContext","getMedia","resolveWaitingForLoadMedia","dispatchJump","goRound","browserPlay","bindBrowserCallback","browserPause","browserStop","browserSeekBackward","browserSeekForward","browserSeekTo","browserNext","browserPrevious","seekToStart","construct","container","document","createElement","style","cssText","body","append","mediaSession","actions","seekbackward","seekforward","seekto","previoustrack","nexttrack","action","setActionHandler","console","warn","skipMediaPlayEvent","properties","key","_key","value","dispatchPlaybackParams","defineProperties","getPlaybackParams","volume","muted","setPlaybackParams","params","_volume","_muted","_playbackRate","_loop","_round","addMedia","autoload","pFlags","is_scheduled","setAttribute","addEventListener","media_unread","fromId","appMessagesManager","readMessages","once","deferred","resolve","w","waitingStorage","then","promise","isSafariBuffering","safariBuffering","setSafariBuffering","setNewMediadata","pictureInPictureElement","artwork","isVoice","title","artist","thumbs","bytes","sizes","h","thumb","appPeersManager","getPeerPhoto","plainText","onlyFirstName","attribute","attributes","_","file_name","performer","IS_APPLE","metadata","MediaMetadata","setCurrentMediadata","playbackParams","cb","willBePlayed","willBePlayedMedia","setSearchContext","context","getSearchContext","prev","reset","loadCount","loadWhenLeft","processItem","onJump","older","onEmptied","reverse","folderId","getPlaybackMediaTypeFromMessage","mediaType","setSingleMedia","wasPlaying","toggleSwitchers","playPaused","removeEventListener","enabled","setPictureInPicture","listenerSetter","removeAll","appMediaPlaybackController","AppMediaViewer","captionTimeout","super","isForDocument","inputFilter","isMediaCompatibleForDocumentViewer","onPrevClick","openMedia","getMessageByPeer","fromRight","onNextClick","onDeleteClick","content","close","onForwardClick","onAuthorClick","Number","MAX_SAFE_INTEGER","threadId","tab","lastMsgId","onDownloadClick","queueId","caption","classList","setCaptionTimeout","clearTimeout","window","onAdditionalScroll","wholeDiv","buttons","btnMenuForward","icon","text","onClick","btnMenuDownload","btnMenuDelete","setBtnMenuToggle","setListeners","forward","author","onCaptionClick","a","contains","spoiler","HTMLAnchorElement","onclick","getAttribute","includes","capture","click","getScheduledMessageByPeer","setCaption","html","entities","totalEntities","maxMediaTimestamp","firstElementChild","prevTargets","nextTargets","mediaTimestamp","setMoverPromise","fwd_from","from_name","noForwards","isServiceMessage","cantForwardMessage","canForward","cantDownloadMessage","download","canDeleteMessage","hide","button","_openMedia","timestamp","date","static","mime_type","VideoPlayer","streamable","onPlaybackRackMenuToggle","onPip","onPipClose","wrapper","setup","canHideControls","playbackRateButton","showOnLeaveToClassName","ignoreClickClassName","parentNode","insertBefore","appendChild","skin","stylePlayer","controls","querySelector","progress","onSeekStart","onSeekEnd","prepend","catch","name","finally","initDuration","buildControls","timeDuration","insertAdjacentHTML","pipButton","querySelectorAll","fullScreenButton","timeElapsed","textContent","toHHMMSS","volumeSelector","leftControls","btn","parentElement","Array","from","togglePlay","requestPictureInPicture","visibility","debounceTime","debouncedPip","debounce","listener","timeout","overlayCounter","code","good","toggleFullScreen","altKey","nextIdx","PLAYBACK_RATES","indexOf","cancelEvent","onFullScreen","bind","hideControls","showControls","setPlaybackRateIcon","onMediaLoad","isPaused","IS_MOBILE","pictureInPictureEnabled","map","rate","regularText","btnMenu","onOpen","onClose","PLAYBACK_RATES_ICONS","className","IS_APPLE_MOBILE","webkitEnterFullscreen","enterFullscreen","isFull","setTimestamp","cleanup","removeListeners","isBetween","num","ZOOM_MIN_VALUE","MEDIA_VIEWER_CLASSNAME","AppMediaViewerBase","topButtons","tempId","preloader","preloaderStreamable","isFirstOpen","pageEl","getElementById","zoomElements","transform","x","y","scale","lastTransform","lastZoomCenter","lastDragOffset","lastDragDelta","onSwipeFirst","ctrlKeyDown","moversContainer","rangeSelector","isGesturingNow","lastGestureTime","Date","now","clampZoomDebounced","isZooming","initialContentRect","getBoundingClientRect","onSwipeReset","draggingType","ignoreNextClick","isZoomingNow","closing","s1","scaleFactor","x1","y1","k","elapsedTime","Vx","abs","Vy","calculateOffsetBoundaries","setTransform","resetZoom","onZoom","initialCenterX","initialCenterY","zoom","zoomAdd","currentCenterX","currentCenterY","dragOffsetX","dragOffsetY","zoomFactor","windowSize","clamp","ZOOM_MAX_VALUE","offsetX","offsetY","scaledCenterX","scaledCenterY","scaleOffsetX","scaleOffsetY","calculateScaleOffset","offsetTop","inBoundsX","inBoundsY","minX","maxX","minY","maxY","getZoomBoundaries","setZoomValue","toFixed","btnOut","btnIn","toggleZoom","setMoverAnimationPromise","tagName","highlightSwitchersTimeout","mover","classNames","findUpClassName","onKeyDown","addZoomStep","ctrlKey","metaKey","onKeyUp","rootScope","log","logger","cancelable","lazyLoadQueue","overlaysDiv","mainDiv","topbar","topbarLeft","onlyMobile","authorRight","avatarEl","nameEl","buttonsDiv","concat","noRipple","step","withTransition","setHandlers","onScrub","addZoom","onMouseDown","onMouseUp","main","innerHTML","onLoadedMore","setNewMover","moveLength","adjustPosition","xDiff","yDiff","setLastGestureTime","swipeHandler","onReset","onFirstSwipe","onSwipe","cancelDrag","onDoubleClick","centerX","centerY","ZOOM_INITIAL_VALUE","changeZoomByPosition","verifyTouchTarget","findUpAsChild","cursor","changeZoom","enable","isVisible","auto","mousedown","zoomValue","setProgress","videoPlayer","lockControls","getZoomBounce","left","right","top","bottom","btnMenuToggle","buttonOptions","direction","Promise","reject","navigationItem","appNavigationController","clear","setMoverToTarget","onAnimationEnd","appMediaViewer","removeGlobalListeners","toggleOverlay","active","toggleGlobalListeners","setGlobalListeners","setMediaTimestamp","replaceChildren","removeCenterFromMover","wasActive","delay","liteMode","realParent","rect","SVGImageElement","SVGForeignObjectElement","needOpacity","overflowElement","visibleRect","getVisibleRect","overflow","vertical","horizontal","containerRect","aspecter","width","HTMLImageElement","setFullAspect","offsetLeft","height","scaleX","scaleY","borderRadius","getComputedStyle","getPropertyValue","brSplitted","str","splitted","split","i","fillPropertyValue","r","parseInt","join","path","opacity","isOut","ret","isFulfilled","isRejected","SVGSVGElement","sizeTailPath","toggleWholeActive","mediaElement","selector","queryFrom","matches","elements","pop","getContext","naturalWidth","naturalHeight","videoWidth","videoHeight","HTMLCanvasElement","drawImage","image","Image","createVideo","clipId","newClipId","newSvg","createElementNS","setAttributeNS","outerHTML","replace","lastElementChild","defs","use","SVGUseElement","d","getAttributeNS","sX","sY","br","v","generatePathData","foreignObject","renderImageFromUrl","display","proportion","upscale","start","diff","_br","moveTheMover","toLeft","windowW","newTransform","p1","newMover","updateMediaSource","toLowerCase","setAuthorInfo","isPeerId","wrapTitlePromise","dialog","wrapEmojiText","oldAvatar","newAvatar","cloneNode","all","updateWithOptions","peerTitle","replaceContent","replaceWith","setAuthorPromise","isDocument","isVideo","useContainerAsTarget","onPop","canAnimate","IS_MOBILE_SAFARI","maxWidth","padding","windowH","mediaSizes","maxHeight","thumbPromise","setAttachmentSize","photoSize","img","downloaded","gotThumb","getStrippedThumbIfNeeded","loadPromise","useController","div","moverVideo","canPlayThrough","createPlayer","ckin","overlay","open","otherMediaViewer","releaseSingleMedia","show","readyState","HAVE_FUTURE_DATA","attach","attachCanPlay","detach","loading","networkState","NETWORK_LOADING","isntEnoughData","unshift","appDownloadManager","toast","langPackKey","error","cancellablePromise","photoSizes","slice","filter","sort","b","fullPhotoSize","cancellableFullPromise","attachPromise","haveImage","fullImage","setManual","onPopState","hash","location","state","debug","isPossibleSwipe","currentHash","overriddenHash","overrideHash","onHashChange","pushState","navigations","manual","handleItem","onEscape","back","onTouchStart","touches","passive","history","scrollRestoration","replaceState","pushItem","noBlurOnPop","findItemByType","index","backByItem","splice","onItemAdded","noHistory","unshiftItem","spliceItems","items","origin","pathname","search","removeItem","removeByType","single","SearchGroup","clearable","clickable","autonomous","onFound","noIcons","list","setActive","childElementCount","AppSearch","searchInput","searchGroups","onSearch","minMsgId","loadedCount","foundCount","searchPromise","searchTimeout","query","listsContainer","scrollable","messages","setVirtualContainer","onChange","searchMore","onScrolledBottom","trim","beginSearch","inputField","input","focus","maxId","limit","res","count","shift","searchGroup","avatarSize","meAsSaved","SearchContextMenu","attachTo","searchSuper","onGotoClick","appImManager","selection","isSelecting","selectionForwardBtn","onSelectClick","toggleByElement","onClearSelectionClick","cancelSelection","selectionDeleteBtn","attachContextMenuListener","callback","init","MouseEvent","preventDefault","cancelBubble","toPeerId","isSelected","isMidSelected","selectedMessages","getSelectedMessages","withSelection","positionMenu","contextMenuController","AppSearchSuper","tabs","prevTabId","middleware","historyStorage","usedFromHistory","loadMutex","nextRates","loadPromises","loaded","loadedChats","firstLoad","monthContainers","mediaTabsMap","asChatList","groupByMonth","hideEmptyTabs","showSender","onTransitionStart","onTransitionEnd","safeAssign","searchContextMenu","navScrollableContainer","navScrollable","nav","tabsMenu","mediaTab","mediaTabs","menuTab","span","ripple","unlockScroll","tabsContainer","handleTabSwipe","prevId","selectTab","children","onTouchMove","lockers","lockTouchScroll","contentTab","searchGroupMedia","canLoadMediaTab","horizontalMenu","tabContent","animate","skipScroll","scrollIntoViewNew","position","startCallback","scrollStartCallback","newMediaTab","onChangeTab","fromMediaTab","scrollTop","scroll","scrollHeight","rect2","onScroll","onMediaClick","targetClassName","mediaSpoiler","event","targets","containerEl","copySearchContext","inputMessagesFilterPhotoVideo","inputMessagesFilterDocument","useHeavyAnimationCheck","unlockAndRefresh","filterMessagesByType","filterMessagesByInputFilter","processEmptyFilter","dialogElement","appDialogsManager","setLastMessagePromise","lastMessage","highlightWord","noop","processPhotoVideoFilter","promises","getMediaFromMessage","wrapped","choosePhotoSize","boxWidth","boxHeight","onlyPreview","withoutPreloader","noPlayButton","photo","noBlur","animationGroup","multiply","images","full","Boolean","processDocumentFilter","withTime","fontWeight","voiceAsMusic","autoDownloadSize","getSize","processUrlFilter","webPage","webpage","entity","display_url","sliced","offset","matchUrl","same","URL","hostname","description","previewDiv","setInnerHTML","wrapAbbreviation","subtitleFragment","htmlToDocumentFragment","wrapRichText","innerText","decodeURIComponent","href","firstChild","wrapPlainText","row","titleRight","subtitle","havePadding","applyMediaElement","performSearchResult","elemsToAppend","sharedMediaDiv","processCallback","results","awaited","method","monthContainer","getMonthContainerByTimestamp","toggleElementCheckbox","afterPerforming","parent","child","loadChats","renderedPeerIds","inputMessagesFilterEmpty","setResults","showMembersCount","dom","peer","getPeer","participants_count","participants","regExp","RegExp","escapeRegExp","cleanSearchText","titleSpan","lastMessageSpan","getChatMembersString","toChatId","username","getPeerUsername","user","appUsersManager","getUser","phone","formatPhoneNumber","formatted","onLoad","arg","getContactsPeerIds","contacts","searchContacts","my_results","globalContacts","showMore","intlElement","isShort","update","dialogsStorage","getDialogs","offsetIndex","filterId","dialogs","minDate","renderRecentSearch","recent","recentSearch","isUser","getUserStatusString","toUserId","getTopPeers","peers","people","subtitleEl","loadMembers","chatId","userId","renderParticipants","membersList","rippleEnabled","li","findUpTag","DIALOG_LIST_ELEMENT_TAG","peerIds","participant","getParticipantPeerId","isAnyChat","rank","getParticipantRank","filtered","filterAsync","deleted","ranks","LOAD_COUNT","getCommonChats","messagesChats","lastChat","chats","appChatsManager","isChannel","appProfileManager","getChannelParticipants","getChatFull","chatFull","loadType","justLoad","used","slicedLength","ids","notFilteredMessages","m","checkForTriggers","getSearch","nextRate","next_rate","loadFirstTime","filters","counters","canViewMembers","canViewGroups","getSearchCounters","firstMediaTab","counter","c","membersTab","loadFirstTimePromise","toLoad","t","findAndSplice","setHours","setDate","dateTimestamp","getTime","containers","month","getFullYear","year","dateElement","haveTimestamps","getObjectKeysAndSort","positionElementByIndex","isBroadcast","hasRights","isForum","getProfile","common_chats_count","cleanScrollPositions","cleanupHTML","goFirst","putPreloader","empty","newInputFilter","copy","setQuery","maxDate","AppSelectPeers","chatsContainer","selected","freezed","loadedWhat","peerType","multiSelect","exceptSelf","tempIds","selfPresence","needSwitchList","design","onInput","cachedContacts","getMoreResults","f","renderResultsFunc","renderResults","splitUp","notRendered","filterPeerTypeBy","section","innerContainer","topContainer","selectedContainer","selectedScrollable","sectionNameLangPackKey","noShadow","checkbox","checked","debouncedInput","appendTo","getResultsPromise","onFirstRender","renderSaved","testSelfSearch","getTempId","getMoreDialogs","archived","pageCount","skipMigrated","newOffsetIndex","chatRightsActions","filterByRights","isEnd","getMoreContacts","every","isGlobalSearch","searchResult","resultPeerIds","arr","getMoreChannelParticipants","channelParticipants","getParticipants","q","chatParticipants","getMoreSomething","call","isNonContactUser","checkboxField","label","isDialog","insertAdjacentElement","offsetWidth","getSelected","addInitial","values","requestAnimationFrame","forceDirection","constructDownloadPreloader","tryAgainOnFail","circle","totalLength","mids","attr","elem","findMediaTargets","anchor","anchorMid","isBubbles","justAudioSelector","selectors","prefix","mediaItems","AudioElement","render","isRealVoice","isOutgoing","is_outgoing","uploadingFileName","getDurationStr","HAVE_CURRENT_DATA","downloadDiv","onTypeLoad","audioEl","out","waveform","Uint8Array","valueCount","result","dataView","DataView","buffer","byteIndex","bitShift","getUint16","decodeWaveform","svg","svgContainer","availW","barHeightMax","minW","maxW","normValue","wfSize","barCount","maxValue","maxDelta","barX","sumI","bar_value","barWidth","createWaveformBars","fakeSvgContainer","waveformContainer","timeDiv","transcriptionState","speechRecognitionDiv","speechRecognitionIcon","speechRecognitionLoader","speechTextDiv","transcribeAudio","progressLine","onTimeUpdate","throttledTimeUpdate","addAudioListener","readyPromise","mousemove","scrub","targetTouches","pageX","scrubTime","wrapVoiceMessage","descriptionEl","audioAttribute","parts","titleEl","middleEllipsisEl","fontSize","sizeType","subtitleDiv","launched","lastChild","wrapAudio","audioTimeDiv","onTypeDisconnect","getTimeStr","imgs","autoDownload","shouldPlay","controlledAutoplay","onDownloadInit","pauseListener","notifyAll","done","total","cancel","Error","playListener","setDownloadFunction","setTargetsIfNeeded","hadSearchContext","useSearch","playWithTimestamp","disconnectedCallback","isConnected","customElements","define","AvatarListLoader","loadMore","photoId","appPhotosManager","getUserPhotos","photos","loadedAllUp","AppMediaViewerAvatar","getPhoto","onAvatarUpdate","openAvatarViewer","getTarget","hadMessage","isObject","data","believeMe","seen","getAvatarQueueKey","AvatarElement","addedToQueue","middlewareHelper","attachClickEvent","updateOptions","wasPeerId","wasThreadId","newPeerId","wrapOptions","create","onlyThumb","putPhoto","isBig","AvatarEdit","clearRect","Button","asLink","asDiv","rippleSquare","disabled","textArgs","tabIndex","ButtonMenuItem","separator","iconDoc","noCheckboxClickListener","textElement","iconElement","noFadeIn","processUrl","fetch","response","color","DOMParser","parseFromString","stroke","strokeWidth","keepOpen","menu","checkForClose","multiline","ButtonMenuSync","ButtonMenu","ButtonMenuToggleHandler","openedMenu","ButtonMenuToggle","attachListenerSetter","onOpenBefore","onCloseAfter","closeTimeout","filteredButtons","_element","BubbleGroup","chat","createAvatar","avatarLoadPromise","avatarContainer","fwdFrom","fwdFromId","isForwardFromChannel","from_id","currentPeerId","avatar","bubbles","firstTimestamp","firstItem","firstMid","lastTimestamp","lastItem","lastMid","updateClassNames","first","bubble","_length","last","insertItem","insertInDescendSortedArray","sortGroupItemsKey","insertGroup","indexOfAndSplice","mount","mounted","onItemUnmount","forEachReverse","mountItem","onItemMount","unmountItem","dateContainer","getDateContainerByTimestamp","dateGroups","_group","dateGroupsLength","unmountedLength","reduce","acc","STICKY_OFFSET","deleteEmptyDateGroups","BubbleGroups","itemsArr","itemsMap","newGroupDiff","sortItemsKey","sortGroupsKey","removeItemFromCache","removeAndUnmountBubble","getItemByBubble","siblings","getSiblingsAtIndex","modifiedGroups","previousSibling","nextSibling","canItemsBeGrouped","groupUngrouped","mountUnmountGroups","toMount","toUnmount","partition","getLastGroup","changeBubbleMid","insertItemToArray","changeItemBubble","changeBubbleByBubble","to","item1","item2","isAllMessagesForum","getMessageThreadId","itemIndex","findGroupSiblingByItem","findGroupSiblingInItems","previousItem","siblingGroupedItem","nextItem","addItemToGroup","addItemToCache","array","getMessageFromId","createItem","SERVICE_AS_REGULAR","getDateForDateContainer","groupMid","splitSiblingsOnGrouping","previousGroup","prepareForGrouping","hadGroup","foundItem","splittedGroups","TAG_NAME","RepliesElement","updated","postKey","replies","leftPart","recent_repliers","stackedAvatars","getPeerId","compareAndUpdate","args","isUnread","read_max_id","max_id","textSpan","iconSpan","rippleContainer","formatNumber","subscribeRepliesThread","updateMessage","makeEdited","edited","makeSponsored","MessageRender","setTime","chatType","editedSpan","sponsoredSpan","isSponsored","sponsored","isMessage","time","views","postAuthor","post_author","postViewsSpan","channelViews","edit_date","edit_hide","pinned","timeSpan","inner","clonedArgs","renderReplies","bubbleContainer","messageDiv","isFooter","repliesFooter","setReply","isReplacing","currentReplyDiv","reply_to_mid","replyToPeerId","reply_to","reply_to_peer_id","originalMessage","originalPeerTitle","titlePeerId","originalMessageFwdFromId","needUpdate","replyMid","fillPromise","isAnyGroup","SuperIntersectionObserver","observing","observingQueue","freezedObservingNew","callbacks","disconnect","toggleObservingNew","queue","isMentionUnread","mentioned","wrapAlbum","attachmentDiv","uploading","prepareAlbum","minWidth","spacing","forMedia","containerWidth","containerHeight","hasSpoiler","mediaDiv","withTail","noAutoplayAttribute","itemWidth","itemHeight","getMediaDurationFromMessage","AppPollResultsTab","resultsDiv","poll","appPollsManager","getPoll","setTitle","quiz","question","percents","voters","total_voters","roundPercents","fragment","createDocumentFragment","hr","answer","answers","answerEl","answerTitle","answerPercents","minHeight","getVotes","option","votesList","votes","vote","user_id","next_offset","lineTotalLength","sum","minIndex","minRemainder","remainder","maxRemainder","pollElement","isClosed","closed","performResults","chosenIndexes","PollElement","setMaxLength","resizePolls","hideQuizHint","onHide","prevQuizHint","prevQuizHintOnHide","prevQuizHintTimeout","isListenerSet","isQuiz","isRetracted","isPublic","isMultiple","chosingIndexes","sentVote","clickHandler","answerIndex","foundIndex","sendVotes","MAX_LENGTH","MAX_OFFSET","svgLines","setLineProgress","getTotalLength","descKey","public_voters","multiple_choice","multipleSelect","descDiv","nextElementSibling","typeDiv","avatarsDiv","close_period","close_date","timeLeftDiv","quizTimer","radius","circumference","PI","period","closeTime","quizInterval","setInterval","timeLeft","strokeDashoffset","strokeDasharray","clearInterval","getResults","answerDivs","numberDivs","footerDiv","viewResults","votersCountDiv","sendVoteBtn","canVote","setVotersCount","detachClickEvent","initQuizHint","solution","solution_entities","toggleHint","textEl","setQuizHint","correctResult","correct","chosen","indexes","sendVotePromise","sendVote","timeEl","forwards","recent_voters","isVoted","hideSendVoteBtn","hideViewResultsBtn","maxPercents","getPercentValue","iterate","fullTime","times","votersCount","multiplier","rtlChars","justRtlDirCheck","IGNORE_ACTIONS","TEST_SCROLL_TIMES","TEST_SCROLL","PEER_CHANGED_ERROR","BIG_EMOJI_SIZES","BIG_EMOJI_SIZES_LENGTH","getMainMidForGrouped","ChatBubbles","unreadOut","skippedMids","bubblesNewByGroupedId","bubblesNew","dateMessages","scrolledDown","isScrollingTimeout","unreaded","unreadedSeen","messagesQueueOnRenderAdditional","firstUnreadBubble","followStack","isHeavyAnimationInProgress","isFirstLoad","passEntities","viewsMids","isTopPaddingSet","renderingMessages","bubblesToEject","bubblesToReplace","setPeerTempId","renderNewPromises","extendedMediaMessages","unreadedObserverCallback","onUnreadedInViewport","viewsObserverCallback","sendViewCountersDebounced","sponsoredMessage","randomId","random_id","viewSponsoredMessage","stickerEffectObserverCallback","isInDOM","onBubblesMouseMove","unhoverPrevious","canSelectBubble","hoverBubble","hoverReaction","setHoverVisible","stickerWrapper","getMessage","getGroupsFirstMessage","getMiddleware","appReactionsManager","getAvailableReactionsByMessage","availableReactions","availableReaction","select_animation","needUpscale","withThumb","needFadeIn","assumeType","sendReaction","onBubblesClick","setInnerPeer","previousElementSibling","chatInner","onDatePick","selectedText","contactDiv","callDiv","callUser","appPaymentsManager","getInputInvoiceByPeerId","reactionElement","reactionsElement","reactionCount","getReactionCount","reaction","stickerEmojiEl","findUpAttribute","bubbleMid","reply_to_top_id","saved_from_msg_id","openThread","message1","getMessageWithReplies","getDiscussionMessage","channel_id","via","appDraftsManager","setDraft","nameDiv","peerIdStr","savedFrom","inputInvoice","messageId","stickerSetInput","checkTargetForMediaViewer","getMidsByMessage","isReplyClick","replyToMid","reply_to_msg_id","ignoreHeavyAnimation","scrollDimensions","forceDown","sliceViewportDebounced","pinnedMessage","setCorrectIndexThrottled","lastScrollDirection","setStickyDateManually","distanceToEnd","getDistanceToEnd","loadedAll","setPeerPromise","processBatch","loadQueue","filterQueue","avatarPromises","groupBubbles","updatePosition","perf","performance","timePromises","groupCollapsed","groupEnd","setUnreadDelimiter","restoreScroll","scrollSaver","prepareToSaveScroll","ejectBubbles","oldBubble","replaceSaved","bubbleGroups","local","updatePlaceholderPosition","setAllSeen","requestHistory","setMessageId","constructBubbles","batchProcessor","process","possibleError","storageKey","sequential","messagesStorageKey","messagesQueuePromise","newItem","_items","scrollingToBubble","scrollToEnd","deleteMessagesByIds","tempMessage","_bubble","groupedId","grouped_id","getMessagesByAlbum","reactionsElements","changeMessage","repliesElement","newDiv","safeRenderMessage","scrollToBubbleIfLast","pending","audioElement","transcribedText","dots","createTextNode","before","deletedMids","wasMainMid","mainMid","changedResults","getMountedBubble","createScrollSaver","save","reactions","appendReactionsElementToBubble","restore","obj","timestamps","removeAttribute","listenTo","findTarget","closest","stickyIntersector","stuck","dateMessage","dateBubble","previousStickyDate","sliceViewport","setScroll","attachContainerListeners","contextMenu","attachListeners","highlightBubble","MAX","replyAfter","swipeAvatar","shouldReply","handleHorizontalSwipe","canSend","_target","_swipeAvatar","initMessageReply","listenerOptions","constructPeerHelpers","updateGradient","renderNewMessage","msgs","setUnreadCount","updateUnreadByDialog","getChat","hadRights","hadPlainRights","canSendPlain","hasPlainRights","canEmbedLinks","finishPeerChange","willSendWebPage","lastUrl","onMessageInput","forum","setPeer","reloadMessages","toDelete","setLoaded","postViewsElements","different","postViews","root","incrementMessageViews","onUpdate","getScheduledMessagesStorage","queuePromise","createResizeObserver","resizeObserver","wasHeight","resizing","skip","scrolled","part","rAF","onResizeEnd","offsetHeight","isScrolledDown","setScrollTopSilently","setEndRAF","cancelAnimationFrame","ResizeObserver","contentRect","realDiff","_part","needScrollTop","destroyResizeObserver","setReactionsHoverListeners","useRafs","getRenderedLength","readUnreaded","readPromise","idleController","bubblesMaxId","getHistoryMaxId","readContents","readHistory","documentDiv","groupedItem","SINGLE_MEDIA_CLASSNAME","isSingleMedia","parents","hasAspecter","albumItem","onGoDownClick","bad","getBubbleByPoint","verticalSide","getViewportSlice","getGroupedBubble","groupId","getMidsByAlbum","getBubbleGroupedItems","findNextMountedBubbleByMsgId","filterCallback","_mid","foundMid","loadMoreHistory","getHistoryTopPromise","getHistoryBottomPromise","getHistory1","destroyScrollable","onScrolledTop","getHistoryStorage","readMaxId","readOutboxMaxId","msgId","destroyBubble","permanent","ignoreOnScroll","ignoreNextScrollEvent","deleteSelectedMids","pollExtendedMediaMessages","getExtendedMedia","setExtendedMediaMessagesPollInterval","pollExtendedMediaMessagesPromise","setTopPadding","setPaddingTo","isPaddingNeeded","clientHeight","paddingTop","unsetPadding","_renderNewMessage","newMessage","getLastBubble","performHistoryResult","scrollToBubbleEnd","scrollToBubble","forceDuration","fallbackToElementStartWhenCentering","whichChild","isChangingHeight","messageInput","margin","axis","getNormalSize","dimensions","gradientRenderer","toNextPosition","getProgress","lastScrollPosition","datasetKey","createDateBubble","today","day","bubbleContent","serviceMsg","fakeBubble","observeStickyHeaderChanges","bubblesToo","cleanupPlaceholders","attachedUnreadBubble","fetchNewPromise","getSponsoredMessagePromise","onAnimateLadder","resolveLadderAnimation","attachPlaceholderOnRender","emptyPlaceholderBubble","cancelMeasure","samePeer","stack","startParam","bindPrefix","middlewarePromise","onChangePeer","isRestricted","topMessage","getPinnedMessagesMaxId","isTarget","followingUnread","savedPosition","overrideAdditionMsgId","getChatSavedPosition","getReadMaxIdIfUnread","getDialogOrTopic","unread_count","foundSlice","findSliceOffset","isJump","isStartButtonNeeded","setStartParam","playMediaWithTimestampAndMid","apiFileManager","setQueueId","messageEntityBotCommand","isBot","additionMsgId","maxBubbleId","oldChatInner","oldPlaceholderBubble","haveToScrollToBubble","fromUp","scrollFromDown","scrollFromUp","willScrollOnLoad","setPeerOptions","processRanks","canShowRanks","acknowledged","ackedResult","setRanksPromise","cached","waitPromise","setPeerCached","finishPeerChangeOptions","mountedByLastMsgId","isPinnedMessagesNeeded","setCorrectIndex","unlock","lastBubble","onRenderScrollSet","afterSetPromise","setFetchReactionsInterval","setFetchHistoryInterval","onScrolledAllDown","isForumTopic","getDialogOnly","unread_mark","markDialogUnread","playMediaWithTimestamp","albumItemMid","textMid","attachment","fetchReactions","getMessagesReactions","needFetchInterval","isFetchIntervalNeeded","apiUpdatesManager","unsubscribeFromChannelUpdates","subscribeToChannelUpdates","historyMaxId","canWrite","renderMessagesQueue","addToQueue","isAvatarNeeded","additionalCallback","wrapMediaSpoiler","processResult","newBubble","originalPromise","renderMessage","albumMids","reactionsMessage","albumMessages","albumMustBeRenderedFull","our","isOurMessage","contentWrapper","isInUnread","unread","customEmojiSize","ignoreAction","langPack","chat_id","service","months","assetName","emoji","playerPromise","lottieLoader","noCache","appStickersManager","getAnimatedEmojiSticker","wrapLocalSticker","isYears","after","is_single","messageMessage","albumTextMessage","messageMedia","needToSetHTML","getAlbumText","bigEmojis","emojiEntities","strLength","curr","setProperty","Infinity","richTextOptions","richText","canHaveTail","isStandaloneMedia","sticker","haveRTLChar","test","topicNameButtonContainer","withIcons","replyMarkup","reply_markup","replyMarkupRows","rows","containerDiv","rowDiv","buttonEl","noLinks","noLinebreaks","botId","viaBotId","same_peer","appInlineBotsManager","checkSwitchReturn","popup","switchInlineQuery","mediaInvoice","extended_media","receipt_msg_id","button_id","toggleDisability","handleUrlAuth","buttonId","haveButtons","column","callbackButtonClick","callbackAnswer","status","messageWithReplies","getMessageWithCommentReplies","withReplies","isOutMessage","nameContainer","canHideNameIfMedia","isMessageEmpty","viewButton","processingWebPage","IS_ANDROID","wrapUrl","telegram_channel","telegram_megagroup","telegram_bot","makeViewButton","box","quote","previewResizer","preview","quoteTextDiv","mediaSize","noInfo","docDiv","file","canTranscribeVoice","site_name","strong","titleDiv","textDiv","isSquare","animated","isEmoji","boxSize","emojiSticker","animatedSticker","staticSticker","noPremium","nopremium","getStickerEffectThumb","isRound","newNameContainer","richTextFragment","getMidsByMid","wrapGroupedDocuments","lastContainer","addClassName","formatCallDuration","reason","contact","contactDetails","contactNameDiv","fullName","first_name","last_name","contactNumberDiv","phone_number","avatarElem","wrapPoll","isTest","extendedMedia","isAlreadyPaid","isNotPaid","innerMedia","wrappedPrice","paymentsWrapCurrencyAmount","total_amount","currency","priceEl","video_duration","videoTime","l","joiner","access_hash","dc_id","file_reference","dotRenderer","needName","titleVia","mustHaveName","isHidden","isForward","replyContainer","withPremiumIcon","getPeerColorById","scam","fake","generateFakeIcon","processRank","createBubbleNameRank","onDestroy","goto","generateTail","documentContainer","documentMessageDiv","viewportSlice","deleteViewportSlice","getSaved","historyResult","needReflowScroll","reflowScrollableElement","setLoadedPromises","firstSlice","lastSlice","both","processLocalMessageRender","detached","backLimit","getHistory","getScheduledMessages","animateAsLadder","additionMsgIds","isAdditionRender","targetMid","sortedMids","topIds","middleIds","bottomIds","getServerMessageId","setBubbles","animationPromise","lastMsDelay","elementsToAnimate","transitionDelay","topRes","middleRes","bottomRes","delays","renderEmptyPlaceholder","BASE_CLASS","listElements","getRestrictionReasonText","stickerDiv","getGreetingSticker","renderPromise","order","channel_post","generateMessageId","start_param","chat_invite","chat_invite_hash","link","invite","processInternalLink","creator","isWaitingForAnimation","noTransition","setOn","generateLocalMessageId","addOffset","generateLocalFirstMessage","fill","peer_id","getOutputPeer","saveMessages","extraSize","ignoreScrollSaving","invisibleTop","invisibleBottom","invisible","side","checkPlaceholders","toggleSponsoredMessage","renderBotPlaceholder","checkIfEmptyPlaceholderNeeded","getSponsoredMessage","sponsoredMessages","messagePromise","_log","processPromise","userFull","bot_info","botInfo","description_document","description_photo","isBackLimit","resultPromise","isFirstMessageRender","serviceStartMessageId","getThreadServiceMessageId","getProfileByPeerId","sup","_promise","mustBeCount","PopupReportMessagesConfirm","onConfirm","noTitle","descriptionLangKey","langKey","isValid","reportMessages","bool","STICKER_EMOJI","header","maxLength","toggleAttribute","PopupReportMessages","titleLangKey","preloadStickerPromise","preloadAnimatedEmojiSticker","buttonsEl","marginTop","PopupSponsored","descriptionLangArgs","isCancel","PopupReactedList","closable","overlayClosable","canViewReadParticipants","canViewMessageReadParticipants","recent_reactions","chosen_order","btnClose","loaders","hasAllReactions","createFakeReaction","hasReadParticipants","readUserIds","getMessageReadParticipants","noDelimiter","chatlist","dialogSize","skipReadParticipants","skipReactionsList","nextOffset","loader","getPromise","getMessageReactionsListAndReadParticipants","combined","stickerContainer","getReactionCached","emoticon","static_icon","docIds","document_id","listEl","setIsChosen","setCanRenderAvatars","renderCounter","allReactionsSticker","REACTIONS_CLASS_NAME","REACTION_CLASS_NAME","CAN_USE_TRANSFORM","ChatReactionsMenu","reactionsMap","players","onScrollProcessItem","onMouseMove","reactionDiv","appear","select","restart","widthContainer","reactionsContainer","reactionsScrollable","callbackify","premium","renderReaction","setVisible","canUseAnimations","scaleContainer","appearWrapper","selectWrapper","skipRatio","isFirst","appear_animation","frameNo","maxFrame","selectLoadPromise","selectPlayer","REACTION_SIZE","ChatContextMenu","onContextMenu","hasOwnProperty","isSelectable","isTextSelected","isSelectionEmpty","isAnchorTarget","isUsernameTarget","selectedMid","isOverBubble","isTargetAGroupedItem","viewerPeerId","canOpenReactedList","linkToMessage","getUrlToMessage","selectedMessagesText","getSelectedMessagesText","initResult","menuPadding","reactionsMenu","reactionsMenuPosition","isReactionsMenuVisible","offsetSize","nextVisiblePart","MIN_NEXT_VISIBLE_PART","minSize","onSendScheduledClick","selectionSendNowBtn","onReplyClick","onFaveStickerClick","unfave","faveSticker","onEditClick","getMessageWithText","initMessageEditing","onCopyClick","execCommand","onCopyAnchorLinkClick","onCopyLinkClick","isPrivate","onPinClick","onUnpinClick","onRetractVote","onStopPoll","stopPoll","filterButtons","setButtons","verifyFavoriteSticker","toAdd","favedStickers","getFavedStickersStickers","some","_doc","hasAttribute","notDirect","scheduleSending","editMessage","scheduleDate","onMessageSent","canEditMessage","selectedMids","getMessageFromStorage","canPinMessage","canDownload","localName","emojiInputsPromise","inputs","getUniqueCustomEmojisFromMessage","sponsor_info","additional_info","withTarget","isArray","canSaveMessageMedia","isGoodType","hasTarget","filterUnique","viewsButton","recentReactions","isViewingReactions","participantsCount","reactedLength","i18nElem","fakeText","AVATAR_SIZE","MAX_AVATARS","PADDING_PER_AVATAR","paddingRight","reactionsCount","fakeElem","readParticipantDates","avatars","totalSize","paddingLeft","emojisButton","setPadding","inputsPromise","appEmojiManager","getCachedCustomEmojiDocuments","docs","getStickerSet","getCustomEmojiDocuments","threadMessage","ChatBackgroundGradientRenderer","_width","_height","_tails","_scrollTails","_curve","_positions","_phases","onWheel","_animatingToNextPosition","_scrollDelta","deltaY","_onWheelRAF","drawOnWheel","floor","ceil","changeTailAndDraw","drawNextPositionAnimated","transitionValue","nextPositionTail","_nextPositionTail","_nextPositionTails","_nextPositionLeft","frames","_frames","drawImageData","_incrementalCurve","hexToRgb","hex","g","getPositions","positions","getNextPositions","phase","curveMax","curve","pos","distances","nextPos","distance","curPosition","tail","changeTail","_tail","_phase","curPos","drawGradient","getGradientImageData","_hctx","createImageData","pixels","centerDistanceY","centerDistanceY2","centerDistanceX","swirlFactor","sqrt","theta","sinTheta","sin","cosTheta","cos","pixelX","pixelY","distanceSum","_colors","distanceX","distanceY","putImageData","_ctx","_hc","colors","alpha","_canvas","fillStyle","fillRect","tails","nextPhaseOnIdx","inc","curves","scrollAnimate","createCanvas","PopupCreatePoll","withConfirm","onSubmitClick","send","radioLabel","isEmpty","isInputEmpty","questions","appendMoreField","handleChange","correctAnswers","optionInputFields","labelOptions","questionInputField","sendMenu","onSilentClick","sendSilent","onScheduleClick","openSide","onContextElement","btnConfirm","setPeerId","dd","settingsCaption","anonymousCheckboxField","multipleCheckboxField","quizCheckboxField","quizSolutionField","setValueSilently","quizElements","quizSolutionCaption","quizHr","quizSolutionContainer","quizSolutionSubtitle","getFilledAnswers","HTMLInputElement","getRichValueWithCaret","validate","quizSolution","valid","quizSolutionEntities","inputMediaPoll","getInputMediaPoll","sendOther","getMessageSendingParams","helperType","clearHelper","questionField","radioField","deleteBtn","HANDLE_EVENT","ACTIVE_CLASS_NAME","AXIS_Y_KEYS","AXIS_X_KEYS","attachListNavigation","onSelect","waitForKey","waitForKeySet","keyNames","getCurrentTarget","setCurrentTarget","scrollTo","hadTarget","fastSmoothScroll","getNextTargetX","currentTarget","isNext","nextTarget","handleArrowKey","property","endProperty","currentRect","targetRect","getNextTargetY","fireSelect","canContinue","attached","resetTarget","_onKeyDown","AutocompleteHelper","hidden","onVisible","listType","attachNavigation","controller","addHelper","toggleListNavigation","fromController","skipAnimation","hideOtherHelpers","StickersHelper","onChangeScreen","checkEmoticon","getStickersByEmoticon","stickers","ready","superStickerRenderer","renderSticker","getMinDate","getMaxDate","setFullYear","getDate","PopupSchedule","initDate","onPick","canSendWhenOnline","noButtons","showOverflowMonths","confirmShortcutIsSendShortcut","controlsDiv","monthTitle","btnSendWhenOnline","EmojiHelper","chatInput","onEmojiSelected","scrollLeft","emojis","checkQuery","firstChar","getBothEmojiKeywords","searchEmojis","AutocompletePeerHelper","doNotShow","listElement","BASE","BASE_CLASS_LIST_ELEMENT","processPeerFullForCommands","botInfos","ignoreCase","commands","command","indexObject","CommandsHelper","getReadyToSend","sendMessage","AutocompleteHelperController","helpers","helper","preserveHelper","MentionsHelper","usernames","getPeerActiveUsernames","insertAtCaret","topMsgId","trimmed","getMentions","ReplyKeyboard","onBodyTouchStart","btnHover","attachButtonListener","checkAvailability","isActive","checkForceReply","touchListener","confirmationPopup","sendContact","sendText","getReplyMarkup","getHistoryStorageTransferable","ANIMATION_GROUP","InlineHelper","queryId","queryAndResultIds","generateQId","resultId","sendInlineResult","clearDraft","_checkQuery","canSendInline","resolveUsername","bot","getInlineResults","botResults","query_id","gifsMasonry","isGallery","gallery","noCommands","mediaContainer","dcId","mimeType","blob","readBlobAsDataURL","dataURL","renderMediaWithFadeIn","observeAnimated","switch_pm","btnSwitchToPM","switchToPM","POSTING_NOT_ALLOWED_MAP","ChatBotCommands","setUserId","modifyAckedResult","acked","modifyAckedPromise","ChatSendAs","onReady","closeBtn","sendAsButtons","previousAvatar","onSendAsMenuToggle","isChanged","updateButtons","sendAsPeerId","changeSendAsPeerId","executeButtonsUpdate","sendAsPeerIds","saveDefaultSendAs","updateAvatar","getDefaultSendAs","getChannelFull","channelFull","default_send_as","updateManual","updatingPromise","wasSkippingAnimation","getSendAs","sendAsPeers","sendAsPeer","premium_required","addedListener","send_voices","send_stickers","send_gifs","send_media","send_plain","send_polls","send_inline","ChatInput","lastTimeType","replyElements","recording","recordCanceled","recordStartTime","lockRedo","canRedoFromHTML","undoHistory","executedHistory","canUndoFromHTML","onCancelRecordClick","recorder","opusDecodeController","onEmoticonsOpen","toggleClass","btnToggleEmoticons","onEmoticonsClose","isUserOnlineVisible","openScheduled","prepareDocumentExecute","undoRedo","needHTML","sameHTMLTimes","currentHTML","handleMarkdownShortcut","formatKeys","markupTooltip","applyMarkdown","getSelection","showLinkEditor","shiftKey","richValue","markdownEntities","caretPos","messageInputField","parseMarkdown","mergeEntities","parseEntities","urlEntities","getWebPagePromise","appWebPagesManager","getWebPage","setTopInfo","noWebPage","onHelperCancel","helperFunc","setTyping","botCommands","activeElement","placeCaretAtEnd","updateBotCommandsToggle","editMsgId","saveDraftDebounced","checkAutocomplete","updateSendBtn","autocomplete","getEmojiEntityFromEmoji","onBtnSendClick","forwarding","flag","blurActiveElement","restricted","voice_messages_forbidden","langPackArguments","releaseMediaPlayback","setRecording","showDiscardPopup","btnCancelRecord","recordingOverlayListener","recordingNavigationItem","sourceNode","analyser","createAnalyser","connect","fftSize","frequencyData","frequencyBinCount","getByteFrequencyData","recordRippleEl","ms","recordTimeEl","needReturn","draft","getCurrentInputAsDraft","no_webpage","originalDraft","canPassEntitiesTypes","draftsAreEqual","onHelperClick","forwardElements","replyToMsgId","inputContainer","rowsWrapperWrapper","rowsWrapper","fakeRowsWrapper","fakeSelectionWrapper","goDownBtn","controlContainer","createButtonIcon","iconBtn","cancelBtn","onHideAuthorClick","isChangingAuthor","onHideCaptionClick","forwardButtons","canToggleHideAuthor","hideSender","showCaption","hideCaption","changePeer","changeForwardRecipient","forwardBtnMenu","forwardWasDroppingAuthor","replyTitle","forwardHover","modifyArgs","newMessageWrapper","replyInTopicOverlay","inputMessageContainer","goDownUnreadBadge","goMentionBtn","goMentionUnreadBadge","goToNextMention","btnScheduled","btnToggleReplyMarkup","replyKeyboard","botCommandsToggle","scaler","botCommandsIcon","onAttachMediaClick","videos","fileInput","accept","willAttachType","attachMenuButtons","giftPremium","canGiftPremium","apiManager","getAppConfig","canGift","premium_gift_attach_menu_icon","appAttachMenuBotsManager","getAttachMenuBots","attachMenu","attachMenuBots","attachMenuBotsButtons","attachMenuBot","inactive","getAttachMenuBotIcon","short_name","requestWebView","bot_id","webViewResultUrl","SANDBOX_ATTRIBUTES","P","titleRaw","telegramWebView","sandbox","iframe","onMount","verifyMap","attachMenuPeerTypeSameBotPM","attachMenuPeerTypeBotPM","attachMenuPeerTypePM","attachMenuPeerTypeChat","attachMenuPeerTypeBroadcast","peer_types","multiple","autocompleteHelperController","stickersHelper","emojiHelper","commandsHelper","mentionsHelper","inlineHelper","btnSendContainer","btnSend","emoticonsDropdown","attachMessageInputField","previousQuery","onFakeInput","saveDraft","center","encoderSampleRate","monitorGain","numberOfChannels","recordingGain","reuseWorker","files","touchMouseDown","onstop","ondataavailable","typedArray","dataBlob","Blob","sendFile","isVoiceMessage","isMedia","objectURL","botStartBtn","toggleBotStartBtnDisability","startBot","pinnedControlBtn","originalChat","pinnedMessageContainer","_center","neededFakeContainer","fakeWrapperTo","oldFakeWrapperTo","needTranslateX","fakeSelectionRect","fakeRowsRect","widthFrom","widthTo","initTranslateX","getNeededFakeContainer","isReplyInTopicOverlayNeeded","appNotificationsManager","isPeerLocalMuted","respectType","hasMentions","unread_mentions_count","ignoreEmptyValue","tsNow","syncDraft","helperToo","clearInput","fromUpdate","getDraft","inputFake","wrappedDraft","wrappingForPeerId","myEntities","apiEntities","wrapDraftText","wrapDraft","currentDraft","setInputValue","createSendAs","firstChange","sendAs","updateOffset","getPlaceholderKey","updateMessageInputPlaceholder","previousSendAs","filteredAttachMenuButtons","filterAttachMenuButtons","ackedPeerFull","ackedScheduledMids","setSendAsCallback","placeholderKey","hasBotCommands","updateBotCommands","updateMessageInput","haveSomethingInControl","isAnonymousSending","oldKey","newKey","isEditingAndLocked","restoreInputLock","contentEditable","oldInputField","withLinebreaks","attachMessageInputListeners","fixSafariStickyInputFocusing","isSendShortcutPressed","range","createRange","sel","setStart","childNodes","collapse","removeAllRanges","addRange","readAllHistory","isContentEditable","commandsMap","canCombine","hasMarkup","resetCurrentFontFormatting","executed","prepareApplyingMarkdown","hasMarkupInSelection","resetCurrentFormatting","setActiveMarkupButton","simulateInputEvent","insertText","insertEntity","isHelper","makeFocused","fullValue","substr","AUTO_COMPLETE_REG_EXP","matchIndex","toString","modify","hadValue","_value","foundHelper","checkInlineAutocomplete","needPlaceholder","setPreloaderShow","btnPreloader","inlineMatch","bot_inline_placeholder","inlinePlaceholder","helperWaitingForward","canSetDraft","fireEvent","clearValue","fixSafariStickyInput","getValueAndEntities","clearReply","endOffset","unicode","pushRecentEmoji","sendingParams","fromPeerId","forwardMessages","dropAuthor","dropCaptions","isDroppingCaptions","sendMessageWithDocument","silent","saveRecentSticker","hideCaptionCheckboxField","replyFragment","usingMids","initMessagesForward","fromPeerIdsMids","fromPeerIds","smth","messagesWithCaptionsLength","peerTitles","titleKey","senderTitles","firstMessage","usingFullAlbum","newReply","intl","peerTitleEl","_message","setReplyToMsgId","callerFunc","replyParent","oldReply","haveReply","CLASS_NAME","REACTION_DISPLAY_BLOCK_COUNTER_AT","ReactionElement","_reactionCount","canRenderAvatars","doNotRenderSticker","hadStickerContainer","getReaction","center_icon","renderDoc","wrapPromise","wrapStickerPromise","displayOn","renderAvatars","isChosen","fireAroundAnimation","REACTION_INLINE_SIZE","REACTION_BLOCK_SIZE","around_animation","stickerPromise","iconPlayer","aroundPlayer","removeOnFrame","REACTIONS_ELEMENTS","ReactionsElement","sorted","middlewareHelpers","connectedCallback","onConnectCallback","isPlaceholder","hasReactions","getAvailableReactions","counts","totalReactions","can_see_list","handleChangedResults","MEDIA_SIZE","wrapReplyDivAndCaption","mediaEl","mediaChildren","withoutMediaType","video_thumbs","videoSize","ReplyContainer","isMediaSet","accumulateMapSet","AppSelection","targetLookupClassName","verifyTarget","selecting","firstTarget","processElement","checkBetween","seenSet","seenLength","elementsBetween","getElementsBetween","toggleByMid","canceledSelection","getElementFromTarget","verifyMouseMoveTarget","removeManual","listenElement","documentListenerOptions","firstRect","lastRect","isHigher","lookupBetweenParentClassName","lookupBetweenElementsQuery","firstIndex","lastIndex","doNotAnimate","onCancelSelection","toggleSelection","navigationType","random","verifyTouchLongPress","isElementShouldBeSelected","appendCheckbox","hasCheckbox","getCheckboxInputFromElement","updateContainer","forceSelection","cantForward","cantDelete","cantSend","getStorageKey","cantForwardDeleteMids","onUpdateContainer","selectedMessagesPromises","toggleCheckboxes","wasSelecting","toggleResult","onToggleSelection","updateElementSelection","toggleMid","unselect","SearchSelection","selectionCountEl","selectionGotoBtn","selectionContainer","btnCancel","attachClickOptions","transitionElement","ChatSelection","isGroupedBubbleSelected","getMidsFromGroupContainer","groupContainer","isGroupedSelected","isGroupedMidsSelected","selectionInputWrapper","selectionLeft","selectionRight","translateButtonsX","isGrouped","groupedCheckboxInput","SendMenu","sendMenuButtons","CheckboxField","restriction","asRadio","stateKey","stateValues","stateValueReverse","stateValue","checkSvg","bg","border","withRipple","withHover","isDisabled","disable","CheckboxFields","createField","info","isNested","nestedTo","nested","asRestrictions","subtitleLangKey","accordion","restrictionText","nodes","nestedCounter","_info","setNestedCounter","titleRow","getNestedCheckedLength","toggleWith","unchecked","processToggleWith","fields","processNestedTo","CodeInputField","assign","lastLength","setLabel","onFill","checkboxes","cancelButton","countries","setCountries","country","default_name","localeCompare","VIRTUAL_COUNTRIES","CountryInputField","hidePicker","hideTimeout","selectCountryByTarget","defaultName","phoneCodeEl","phoneCode","countryCode","lastCountrySelected","lastCountryCodeSelected","country_codes","_countryCode","country_code","onCountryChange","liMap","arrowDown","selectList","initSelect","noPhoneCodes","iso2","liArr","spanEmoji","mouseDownHandlerAttached","onKeyPress","names","abbr","word","blur","selectCountryByIso2","countryName","DivAndCaption","DotRenderer","dpr","devicePixelRatio","prepare","generateDot","adding","Path2D","arc","mOpacity","draw","dot","addOpacity","easedOpacity","globalAlpha","renderFirstFrame","EditPeer","_disabled","uploadAvatar","changedLength","requiredLength","requiredValidLength","inputFields","required","nextBtn","withoutAvatar","doNotEditAvatar","avatarEdit","_upload","popupOptions","lockWithPromise","unlockOnSuccess","GifsTab","gifsContainer","EmoticonsDropdown","masonry","EMOTICONSSTICKERGROUP","getGifs","processInvisibleDiv","ANIMATIONGROUP","AppGifsTab","onGifsClick","fileId","inputSearch","gifsDiv","onCloseAfterTimeout","newSearch","gifBotPeerId","AppStickersTab","setsDiv","stickerSet","toggleStickerSet","installed_date","renderFeatured","renderSet","countDiv","stickersDiv","documents","withLock","getFeaturedStickers","coveredSets","filterRendered","covered","searchStickerSets","scrollOptions","transitionFunction","ignoreOutClickClassName","tabId","onSelectTabClick","stickersTab","gifsTab","rights","searchButton","emojiTab","checkRights","canSendToPeer","tabsEl","savedRange","getGoodRange","onOpened","refresh","onClosed","getSavedRange","setStartAfter","newRange","cloneRange","collapsed","node","endContainer","newStartNode","nodeType","TEXT_NODE","nodeValue","ELEMENT_NODE","selectNode","newOffset","deleteContents","HIDE_EMOJI_TAB","INIT_TAB_ID","lastMouseMoveEvent","mouseMoveEventAttached","onMouseOut","getElement","forceClose","addLazyLoadQueueRepeat","divs","intersector","getVisible","clearVisible","rangeCount","getRangeAt","menuOnClick","emoticons","menuScroll","prevTab","jumpedTo","getElementPosition","elementPosition","scrollToTab","scrollingToContent","getCategoryByContainer","which","getCategoryByMenuTab","additionalOffset","setActiveStatic","clientWidth","sendDocId","loadedURLs","appendEmoji","unify","kek","wrapSingleEmoji","fixEmoji","getEmojiFromElement","superEmoji","stickerEmoji","EMOJI_RECENT_ID","EMOJI_RECENT_CATEGORY","CUSTOM_EMOJI_RECENT_CATEGORY","EMOJI_CATEGORIES","category","EMOJI_ELEMENT_SIZE","EmojiTab","onCategoryVisibility","categoriesMap","renderer","newChildren","customEmojis","customEmojiElement","clearCanvas","onContentClick","isStandalone","activeElements","menuInnerScroll","intersectionOptions","categoriesIntersector","menuOnClickResult","innerScrollWrapper","preparedMap","noRegularEmoji","titleLangPackKey","createLocalCategory","unified","addEmojiToCategory","batch","getRecentEmojis","stickerSetId","getLocalStickerSet","getCustomEmojis","recentCustom","mainSet","sets","recentCategory","categories","recentCustomCategory","CUSTOM_EMOJI_RECENT_ID","createRendererForCategory","toggleLocalCategory","resizeCategories","renderStickerSet","toggleCustomCategory","postponedEvent","positionCategory","toggleRenderers","ignore","ignoreSettingDimensions","setDimensionsFromRect","deleteCategory","isCategoryVisible","forceRender","closeScrollTop","createCategory","menuTabPadding","stickerEmojiRaw","setCategoryItemsHeight","getCustomCategory","hasPremium","canSeeCustomCategory","activeEmoji","spliceExceed","onLocalCategoryUpdate","LazyLoadQueueRepeat","parallelLimit","onVisibilityChange","elementsMap","queueItem","wasSeen","setProcessQueueTimeout","SuperStickerRenderer","regularLazyLoadQueue","checkAnimationContainer","processVisible","processInvisible","unobserveAnimated","StickersTabCategory","noMenuTab","getContainerSize","getElementMediaSize","gapX","gapY","elementSize","itemsPerRow","EmoticonsTabC","categoryItemsClassName","postponedEvents","categoriesByMenuTabMap","localCategories","menuWrapper","isLocal","esgWidth","customProperties","posItems","foundMenuScroll","posMenu","notMountedItems","notMountedMenus","itemsIdx","menuIdx","StickersTab","setFavedLimit","categoryAppendStickers","clearCategoryItems","onCategoryStickers","deleteSticker","unshiftSticker","favedCategory","clearButton","clearRecentStickers","premiumCategory","getLimit","getRecentStickersStickers","getAllStickers","getPremiumStickers","isPremium","race","rendererLazyLoadQueue","faved","createStickersContextMenu","verifyRecent","unshiftRecentSticker","deleteRecentSticker","generateDelimiter","delimiter","isScam","LazyLoadQueueRepeat2","spliced","findAndSpliceAll","GifsMasonry","scrollPromise","processVisibleDiv","noPreview","transitionTime","scrollableX","proxy","Proxy","apply","that","selectTarget","result1","canChange","mutateCallback","useStripe","indicator","currentIndicator","shiftLeft","insertRichTextAsHTML","createCustomEmojiRendererForInput","customEmojiRenderer","richInputHandler","customEmojiElements","ces","documentFragmentToHTML","pre","getCaretPosNew","onBeforeInput","inputType","removeExtraBOMs","originalEvent","clipboardData","getData","usePlainText","filterEntity","curChild","lines","textLength","lineIndex","line","nextLine","correctedText","entities2","InputState","wrappingDraft","processCustomEmojisInInput","hasSet","InputField","showLengthOn","canBeEdited","labelText","onInputCallbacks","isCollapsed","focusOnNext","clientX","inputMode","labelEl","showingLength","wasError","inputLength","isError","selectNodeContents","selectElementContents","fromSet","originalValue","isValidToChange","setDraftValue","setOriginalValue","setState","Valid","setError","USELESS_REG_EXP","InputFieldAnimated","updateInnerHTML","setHeight","noAnimation","newHeight","currentHeight","transitionDuration","onChangeHeight","InputSearch","prevValue","onClearClick","onClear","searchIcon","clearBtn","LazyLoadQueue","getItem","addElement","LazyLoadQueueIntersector","inProcess","loadItem","intersectorTimeout","processQueue","MediaProgressLine","useTransform","onLoadedData","setSeekMax","progressRAF","setLoadProgress","onProgress","filledLoad","buf","buffered","numRanges","nearestStart","end","realDuration","seek","testQueue","pendingTest","setTestQueue","testElement","getElementWidth","mapped","firstTime","font","textWidth","elementWidth","newElementWidth","widthChanged","smallerText","smallerWidth","smallerTextLength","half","half1","half2","MiddleEllipsisElement","PasswordMonkey","passwordInputField","needFrame","currentFrame","setSpeed","onVisibilityClickAdditional","passwordVisible","setDirection","curFrame","TrackingMonkey","playAnimation","frame","idleAnimation","PasswordInputHelpers","onVisibilityClick","toggleVisible","stealthy","PasswordInputField","PeerProfileAvatars","draggable","loadCallback","intersectionObserver","loadCallbacks","addTab","gradient","arrowPrevious","arrowNext","checkScrollTop","SWITCH_ZONE","freeze","_e","clickX","toRight","cancelNextClick","lastDiffX","lastX","SCALE","TRANSLATE_TEMPLATE","addIndex","loadNearestToTarget","filterChatPhotosMessages","chat_photo","generateFakeAvatarMessage","activeTab","photo_id","setText","PeerProfile","bio","isAnonymous","getUserPhone","notifications","togglePeerMute","setPeerStatus","setMoreDetails","n","fillUsername","self","fillUserPhone","setAvatar","setPeerStatusInterval","needClear","useWhitespace","ignoreSelf","clearSetMoreDetailsTimeout","canBeDetailed","_setAvatar","isTopic","oldAvatars","getUsernamesAlso","also","anchorCopy","formatUserPhone","fillNotifications","notificationsRow","fillName","fillRows","fillProfileElements","cleaned","_setMoreDetails","peerFull","getMiddlewarePromise","about","exportedInvite","exported_invite","address","setMoreDetailsTimeout","isPeerRestricted","setPromise","makeError","generateTitleIcons","noVerifiedIcon","noFakeIcon","noPremiumIcon","verified","use2","generateVerifiedIcon","emojiStatus","emoji_status","generatePremiumIcon","weakMap","WeakMap","PeerTitle","setOptions","setHasInner","hasInner","fromName","limitSymbols","topic","forumTopic","getTopicIconPromise","icons","topicIcon","getPeerTitle","PopupAvatar","cropper","crop","removeHandlers","h6","cropContainer","contents","onload","originalImage","cropComponent","cropImage","event_state","cropLeft","cropTop","cropWidth","cropHeight","scaledRatio","overlayColor","CROPWIDTH","CROPHEIGHT","updateCropSize","updateCropImage","startMoving","keyHandler","imgZoom","newWidth","String","fromCharCode","charCode","stopPropagation","container_width","container_height","container_left","container_top","mouse_x","scrollX","mouse_y","clientY","pageY","scrollY","saveEventState","moving","endMoving","currentTouch","complete","toBlob","darkenCanvas","onCrop","postCanvas","ctx","PopupDatePicker","selectedDate","selectedMonth","setMonth","getMonth","minMonth","prevBtn","maxMonth","onDateClick","selectedEl","setTimeTitle","monthsContainer","handleTimeInput","onOverflow","maxString","hoursInputField","minutesInputField","number","setMinutes","getMinutes","getHours","popupCenterer","timeOptions","minute","hour","sendDate","dateOptions","weekday","renderElement","firstDate","weekStartDate","getDay","dayIndex","clonedDate","PopupDeleteDialog","peerTitleElement","getDialogType","callbackLeave","flush","leave","flushHistory","callbackDelete","titleArgs","descriptionArgs","isDanger","titleLangArgs","PopupDeleteMessages","revoke","deleteScheduledMessages","deleteMessages","isMegagroup","_hasRights","canRevoke","PopupForward","peerIdMids","chatRightsAction","peerTypes","messagesPromises","DEFAULT_APPEND_TO","appendPopupTo","onFullScreenChange","PopupElement","reAppend","MANAGERS","withoutOverlay","attachScrollableListeners","btnConfirmOnEnter","buttonsElements","langArgs","POPUPS","setClassOn","attachBorderListeners","onContentUpdate","popupConstructor","ctor","addCancelButton","PopupJoinChatInvite","chatInvite","request_needed","broadcast","importChatInvite","savePhoto","peopleCount","pin","descriptionPremium","descriptionLocked","folders","_a","limitPremium","isLocked","limitContainer","hint","free","setHintActive","showLimitPopup","appConfig","premium_purchase_blocked","ONE_HOUR","PopupMute","mutePeer","muteUntil","radioForm","createPosterFromMedia","scaleMediaElement","quality","getGifDuration","arrayBuffer","currentPopup","getCurrentNewMediaPopup","PopupNewMedia","ignoreInputValue","attachFile","willAttach","shouldCompress","itemDiv","defineNotNumerableProperties","attachMedia","attachDocument","sendFileDetails","backgroundColor","onlyVisible","actionsPromises","captionMaxLength","captionLengthMax","canSendPhotos","send_photos","canSendVideos","send_videos","canSendDocs","send_docs","changeType","hasAnyMedia","mimeTypes","changeGroup","canGroupSomething","changeSpoilers","canToggleSpoilers","wasInputValue","attachFiles","createContextMenu","applyMediaSpoiler","removeMediaSpoiler","findElement","widthStr","heightStr","containerWidthStr","containerHeightStr","toDataURL","strippedBytes","reveal","destroyAfter","appendDrops","mediaCount","mediaWithSpoilers","addFiles","toPush","_file","lastModified","foundBad","sendFileParams","noSound","shake","scaledBlob","sendAlbum","modifyMimeTypeForTelegram","scaleImageForTelegram","convertWebp","PHOTO_SIDE_LIMIT","revokeObjectURL","startsWith","audioDecodedByteCount","webkitAudioDecodedByteCount","onseeked","onerror","createPosterFromVideo","scaled","isPhoto","isAudio","Audio","onRender","foundPhotos","foundVideos","foundFiles","appendMediaToContainer","calcImageInBox","firstType","oldSendFileDetails","albumContainer","o","oldParams","stringResults","numberResults","replaceNonNumber","CARD_BRAND_REGEXP","visa","mastercard","amex","discover","diners","diners14","jcb","unionpay","elo","mir","CARD_BRANDS","minLength","cvcMaxLength","cvcMinLength","unknown","detectCardBrand","card","sanitizedCard","brand","detectUnifiedCardBrand","createArray","delta","charCodeAt","buggedRegExp","getDistanceFromBuggedToNormal","char","fixBuggedNumbers","makeOptionalCharacter","consumed","makeRequiredCharacter","partial","wrapCharacterRegExpFactory","optional","_regExp","source","makeCharacter","makeMonthDigitPatternCharacter","digit","capitalCharacter","toUpperCase","cleanedResult","formattingCharacter","str1","makeFormattingCharacter","optionalPattern","spaceCharacter","yearOptionalPattern","sixteenPattern","fifteenPattern","requiredPostcodes","generateFourPattern","cardFormattingPatterns","cardNumber","cardExpiry","cardCvc","cardCvcFromBrand","pattern","postalCodeFromCountry","optionalDigits","accumulateLengths","strs","accumulate","nbspRegExp","makeValidationError","validateCardNumber","sanitized","getCardInfoByNumber","ignoreIncomplete","validateCompleteCardNumber","makeCardNumberError","validateCardExpiry","monthStr","yearStr","_year","nextMonth","isNaN","validateExpiry","createVerificationIframe","allow","PopupPaymentVerification","openPathAfter","path_full","InputFieldCorrected","lastKeyDown","deleting","lastTransformed","getPattern","pushRest","autocorrectComplete","selectionStart","selectionEnd","character","getCharacter","meta","formatInputValueByPattern","formatMethod","transformedValue","validateNew","onBlur","justReturn","validateMethod","validateAnyIncomplete","errorKeys","handleInputFieldsOnChange","_onChange","original","createCountryZipFields","zip","countryInputField","postcodeInputField","SUPPORTED_NATIVE_PROVIDERS","PopupPaymentCard","paymentForm","savedCard","native_provider","cardOut","token","credentials","can_save_credentials","cardSection","nativeParams","JSON","parse","native_params","lastBrand","lastBrandImg","brandIconTempId","cardInputField","invalid","incomplete","transformed","getPaymentBrandIconPath","setBrandIcon","cvcInputField","nameInputField","need_cardholder_name","expireInputField","switchFocusOrder","previousInputField","nextInputField","inputFieldsRow","form","billingSection","need_country","need_zip","canSave","saveCheckboxField","saveRow","payButton","PaymentButton","expiryFull","expiryMonth","expiryYear","cvc","cardholderName","nativeProvider","URLSearchParams","headers","publishable_key","json","expiration_month","expiration_year","security_code","public_token","stringify","PopupPaymentCardConfirmation","passwordState","captionArgs","inputCheckPassword","passwordManager","getInputCheckPassword","tmpPassword","invokeApi","password","handled","PopupPaymentShipping","invoice","savedInfo","saved_info","addressSection","address1InputField","address2InputField","cityInputField","stateInputField","receiverSection","emailInputField","telInputField","shipping_address_requested","name_requested","email_requested","phone_requested","validateEmail","matchEmail","validatePhone","selectedCountry","shipping_address","street_line1","street_line2","city","country_iso2","post_code","email","requestedInfo","validateRequestedInfo","shippingAddress","ADDRESS_STREET_LINE1_INVALID","ADDRESS_STREET_LINE2_INVALID","ADDRESS_COUNTRY_INVALID","ADDRESS_CITY_INVALID","ADDRESS_STATE_INVALID","ADDRESS_POSTCODE_INVALID","REQ_INFO_NAME_INVALID","REQ_INFO_EMAIL_INVALID","REQ_INFO_PHONE_INVALID","focusField","PopupPaymentShippingMethods","shippingOption","shipping_options","prices","amount","lastShippingId","PopupPayment","isReceipt","tipButtonsMap","confirmed","onConfirmed","popupPaymentVerification","itemEl","detailsClassName","photoEl","linesClassName","linesEl","botName","preloaderContainer","getPaymentReceipt","msg_id","getPaymentForm","savedCredentials","saved_credentials","lastRequestedInfo","providerPeerTitle","getState","provider_id","wrapAmount","skipSymbol","isRecurring","recurring","peerTitle2","makeLabel","pricesClassName","makePricesElements","price","_label","wrappedAmount","pricesElements","getTipsAmount","shippingAmount","setTotal","totalAmount","totalLabel","payI18n","canTip","max_tip_amount","tip_amount","tipsClassName","currencyData","getInputValue","setInputWidth","getTextWidth","unsetActiveTip","tipEl","tipsLabel","haveToIgnoreEvents","onSelectionChange","ignoreNextSelectionChange","onFocus","onFocusOut","symbol","space_between","symbol_left","tipsEl","tipClassName","tipButtons","suggested_tip_amounts","tipAmount","prevTipEl","setRowIcon","createMedia","createRow","noWrap","setRowTitle","setCardSubtitle","methodRow","onMethodClick","previousCardDetails","previousToken","credentials_title","providerRow","providerAvatar","shippingAddressRow","shippingNameRow","shippingEmailRow","shippingPhoneRow","shippingMethodRow","lastShippingOption","onShippingAddressClick","onShippingMethodClick","setShippingTitle","postAddress","setShippingInfo","setShippingOption","lastShippingPricesElements","shipping","acceptTermsCheckboxField","recurring_terms_url","acceptTermsRow","recurringElements","lastTmpPasword","missingInfo","tmp_password","paymentResult","sendPaymentForm","form_id","_passwordState","valid_until","PopupPeer","PopupPickUser","PopupSendNow","sendScheduledMessages","PopupStickers","isEmojis","onStickersClick","updateAdded","stickersFooter","onStickerSetUpdate","_set","updateButton","loadStickerSet","createStickerSetElements","headerRow","buttonRight","added","itemsContainer","setsPromises","firstSet","isStickerPack","onSend","containersPromises","toggleStickerSets","isAdd","buttonAppend","installed","PopupPinMessage","unpin","canUnpin","oneSide","unpinAllMessages","hidePinnedMessages","updatePinnedMessage","buttonText","getPinnedMessagesCount","pinButtonText","ProgressivePreloader","isUpload","attachMethod","loadFunc","constructContainer","bold","constructDownloadIcon","downloadSvg","cancelSvg","func","startTime","onEnd","notify","TRANSITION_TIME","addNotifyListener","Layouter","ratios","countRatios","proportions","countProportions","averageRatio","maxSizeRatio","layout","ComplexLayouter","layoutTwo","layoutThree","layoutFour","layoutTwoTopBottom","layoutTwoLeftRightEqual","layoutTwoLeftRight","layoutThreeLeftAndOther","layoutThreeTopAndOther","layoutFourTopAndOther","layoutFourLeftAndOther","geometry","sides","RectPart","minimalWidth","secondWidth","firstWidth","firstHeight","thirdHeight","secondHeight","rightWidth","leftWidth","thirdWidth","h0","w0","w2","w1","h1","h2","ratio","cropRatios","attempts","multiHeight","pushAttempt","lineCounts","heights","second","third","fourth","optimalAttempt","optimalDiff","attempt","lineCount","totalHeight","minLineHeight","bad1","bad2","optimalCounts","optimalHeights","rowCount","colCount","lineHeight","col","widthItem","heightItem","borderTopLeftRadius","borderBottomLeftRadius","borderTopRightRadius","borderBottomRightRadius","putAvatar","renderThumbPromise","thumbImage","isFullLoaded","loadThumbPromise","stripped_thumb","getPreviewURLFromBytes","sequentialDom","myId","getForumTopic","avatarAvailable","avatarRendered","appAvatarsManager","isAvatarCached","getPeerInitials","returnDiv","setButtonLoader","RadioField","alignRight","RadioForm","radios","RangeSelector","events","setFilled","filled","stepStr","decimals","_removeListeners","addProgress","rectMax","offsetAxisValue","rippleClickId","attachListenerTo","handler","drawRipple","clickId","_handler","touchStartFired","clickY","isRippleUnneeded","touchEnd","setContent","Row","checkboxFieldOptions","subtitleRight","subtitleRow","subtitleLangArgs","isToggle","withCheckboxSubtitle","titleRightSecondary","titleRightContent","_title","createTitle","navigationTab","buttonRightLangKey","_subtitle","createSubtitle","midtitle","_midtitle","createMidtitle","disableWithPromise","makeSortable","sortIcon","toggleSorting","CreateRowFromCheckboxField","RadioFormFromRows","RadioFormFromValues","checkedRadioField","ScrollableBase","logPrefix","onScrollMeasure","needCheckAfterAnimation","scrollPosition","scrollProperty","addScrollListener","addedScrollListener","removeScrollListener","removeHeavyAnimationListener","Scrollable","onScrollOffset","withPaddingContainer","maxScrollTop","ScrollableX","splitCount","scrollHorizontally","deltaX","scrollWidth","SettingSection","fakeGradientDelimiter","generateContentElement","nameArgs","captionOld","generateSection","AppNewGroupTab","isGeoChat","inputWrapper","groupNameInputField","groupLocationInputField","valueCheck","userLocationCoords","userLocationAddress","createChannel","geo_point","megagroup","inputFile","editPhoto","inviteToChannel","createChat","chatsSection","new","startLocating","usersPromise","myUserPromise","getSelf","users","setTitlePromise","myUser","joined","isLast","geolocation","getCurrentPosition","lat","coords","latitude","long","longitude","uri","display_name","GeolocationPositionError","PrivacyType","getPrivacyRulesDetails","rules","types","allowPeers","disallowPeers","rule","PrivacySection","onRadioChange","captions","captionElement","radioSection","exceptions","radioRows","skipTypes","noExceptions","exceptionTexts","exception","_peerIds","slider","createTab","skippable","takeOut","newPeerIds","generateStr","splitPeersByType","selectedPeerIds","appPrivacyManager","getPrivacy","inputKey","setRadio","eventListener","chatKey","usersKey","getUserInput","setPrivacy","AppPrivacyPhoneNumberTab","captionEl","mePath","phoneSection","sCaption","AppTwoStepVerificationSetTab","inputContent","btnReturn","sliceTabsUntilTab","AppSettingsTab","canFocus","isFirstInput","AppTwoStepVerificationEmailConfirmationTab","codeInputField","confirmPasswordEmail","goNext","btnChange","btnResend","cancelPasswordEmail","AppTwoStepVerificationEmailTab","resendPasswordEmail","onOpenAfterTimeout","onContinueClick","btnContinue","btnSkip","toggleButtons","updateSettings","currentPassword","plainPassword","newPassword","symbols","AppTwoStepVerificationHintTab","onSkipClick","saveHint","AppTwoStepVerificationReEnterPasswordTab","monkey","verifyInput","AppTwoStepVerificationEnterPasswordTab","isNew","has_password","getStateInterval","_state","check","auth","AppTwoStepVerificationTab","removeTabFromHistory","btnChangePassword","btnDisablePassword","btnSetRecoveryEmail","has_recovery","btnSetPassword","AppPrivacyLastSeenTab","AppPrivacyProfilePhotoTab","AppPrivacyForwardMessagesTab","AppPrivacyAddToGroupsTab","AppPrivacyCallsTab","AppActiveSessionsTab","Session","app_name","app_version","ip","date_active","date_created","device_model","system_version","platform","authorizations","session","btnTerminate","otherSection","onError","onTerminateClick","menuElement","AppBlockedUsersTab","btnAdd","toggleBlock","blocked","getBlocked","convertKeyToInputKey","AppPrivacyVoicesTab","AppActiveWebSessionsTab","sessions","region","domain","browser","appSeamlessLoginManager","resetWebAuthorizations","leftLength","resetWebAuthorization","AppPrivacyAndSecurityTab","fromTab","globalPrivacy","getGlobalPrivacySettings","contentSettings","webAuthorizations","getWebAuthorizations","SUBTITLE","blockedPeerIds","blockedUsersRow","twoFactorRowOptions","email_unconfirmed_pattern","twoFactorRow","activeSessionsRow","updateActiveSessions","websitesRow","updateActiveWebsites","websites","setBlockedCount","updateBlocked","rowsByKeys","numberVisibilityRow","lastSeenTimeRow","photoVisibilityRow","callRow","linkAccountRow","groupChatsAddRow","voicesRow","updatePrivacyRow","disallowLength","allowLength","destroyed","setGlobalPrivacySettings","archive_and_mute_new_noncontact_peers","settings","onPremiumToggle","autoarchive_setting_available","_enabled","sensitive_enabled","sensitive_can_change","payment","clearSavedInfo","deleteButton","clearAllDrafts","auths","AppPowerSavingTab","infoSection","checkboxFields","wrap","mainKey","flatten","field","created","onAllChange","wasAll","appStateManager","setByKey","RangeSettingSelector","initialValue","minValue","writeValue","valueDiv","valueContainer","AppGeneralSettingsTab","themes","chatBackgroundButton","initArgs","getLiteModeStatus","animationsCheckboxField","animationsRow","liteModeRow","themesContainer","themesMap","currentTheme","themeController","isNight","applyThemeOnItem","theme","wallPaperContainer","wallPaperContainers","lastOnFrameNo","lastActive","onFrameNo","availableBaseThemes","defaultThemes","default","themeSettings","base_theme","wallPaper","wallpaper","emoticonContainer","bubbleIn","dayRow","nightRow","systemRow","newIsNight","enterRow","ctrlEnterRow","kilometersRow","milesRow","formats","format","runFirst","getNextTimeout","_callback","run","eachTimeout","getSeconds","eachMinute","toLocaleTimeString","AppChatFoldersTab","filtersRendered","animationData","renderFolder","dialogFilter","non_contacts","broadcasts","bots","folder","getFolderDialogs","channels","filtersStorage","getFilter","setInitFilter","localId","getInitArgs","createFolderBtn","foldersSection","suggestedSection","canCreateFolder","onFiltersContainerUpdate","renderFiltersPromise","toggleAllChats","getSuggestedFilters","loadAnimationPromise","onSort","prevIdx","newIdx","updateDialogFiltersOrder","getDialogFilters","getSuggestedDialogsFilters","suggestedFilters","includePeerIds","excludePeerIds","pinnedPeerIds","createDialogFilter","AppNotificationsTab","NotifySection","enabledRow","typeText","previewEnabledRow","inputNotifyPeer","getNotifySettings","notifySettings","applySettings","isMuted","show_previews","mute","showPreviews","inputSettings","mute_until","flags","updateNotifySettings","notify_settings","contactsSignUpRow","soundRow","sound","getContactSignUpNotification","setContactSignUpNotification","AppLanguageTab","languages1","lang_pack","languages2","rendered","webLangCodes","language","lang_code","native_name","autoDownloadPeerTypeSection","contactsCheckboxField","privateCheckboxField","groupsCheckboxField","channelsCheckboxField","AppAutoDownloadPhotoTab","AppAutoDownloadFileTab","debouncedSave","sizeMax","MIN","MAX_RANGE","upTo","formatBytes","AppAutoDownloadVideoTab","AUTO_DOWNLOAD_FOR_KEYS","private","AppDataAndStorageTab","autoCheckboxField","autoRow","resetButton","deepEqual","setSubtitles","setAutoDownloadSubtitle","photoRow","videoRow","fileRow","openTab","tabConstructor","autoDownloadNew","onDisabledChange","peerKeys","enabledKeys","isAll","AppQuickReactionTab","getQuickReaction","quickReaction","setDefaultReaction","AppStickersAndEmojiTab","allStickers","suggestStickersRow","none","setStickersSuggestDescription","setStickersSuggest","listenForClick","reactionsRow","renderQuickReaction","getCustomEmojiDocument","loopStickersRow","suggestEmojiRow","bigEmojiRow","dynamicPackOrderRow","stickerSets","stickersContent","reorderStickerSets","logOut","edit","profile","changeAvatarBtn","upload","uploadProfilePhoto","updateChangeAvatarBtn","languageArgs","devicesRow","languageRow","buttonsSection","getEditProfileArgs","editProfileArgs","getAuthorizations","overwrite","getAuthorizationsPromise","AppNewChannelTab","channelNameInputField","channelDescriptionInputField","onLengthChange","channelId","PopupCreateContact","importContact","lastNameInputField","editPeer","AppContactsTab","openContacts","isContact","sortedUserList","createList","renderPage","AppArchivedTab","wasFilterId","ul","AppPeopleNearbyTab","isLocationWatched","parseDistance","startWatching","latestLocationSaved","getLocated","accuracy","watchPosition","isLongitudeDifferent","isLatitudeDifferent","distanceCheck","calculateDistance","stopWatching","lat1","long1","lat2","long2","asin","LEFT_COLUMN_ACTIVE_CLASSNAME","AppSidebarLeft","sidebarEl","sidebarHeader","onContactsClick","backBtn","btnArchive","isDialogsLoaded","themeCheckboxField","sessionStorage","kz_version","installPrompt","toolsBtn","btnMenuFooter","rel","archivedCount","newBtnMenu","updateBtn","reload","initSearch","unreadPeerIds","checkUpdateInterval","cache","ok","hasUpdate","onResize","documentElement","searchContainer","pickedElements","selectedPeerId","selectedMinDate","selectedMaxDate","updatePicked","removeProperty","unselectEntity","renderEntity","dates","dateData","pushRecentSearch","peopleContainer","hideNewBtnMenuTimeout","transition","activeClassName","clearRecentSearchBtn","clearRecentSearch","appSidebarLeft","AppAddMembersTab","attachToPromise","isPrivacy","removeLoader","averageColorFromCanvas","pixel","getImageData","pixelsLength","outPixel","Uint8ClampedArray","highlightningColor","rgba","ColorPicker","hue","saturation","lightness","onGrabStart","boxDragger","onGrabEnd","sliders","hueDragger","hexInputField","rgbInputField","setColor","rgbRegExp","attachBoxListeners","attachHueListeners","attachGrabListeners","boxRect","saturationHandler","hueRect","hueHandler","updateHexInput","updateRgbInput","rgb","boxX","percentY","boxY","percentHue","hueX","updatePicker","getCurrentColor","rgbaArray","hexa","hsl","hsla","posX","posY","lightnessX","lightnessY","AppBackgroundColorTab","_applyColor","updateColorPicker","colorPicker","background_color","pushToState","onColorChange","applyColor","gridSection","grid","throttle","isColored","AppBackgroundTab","clicked","wallPapersByElement","elementsByKey","onUploadClick","requestFile","endsWith","createObjectURL","File","prepareWallPaperUpload","uploadPromise","uploadWallPaper","uploadDeferred","getWallPaperKey","setBackgroundDocument","addWallPaper","onResetClick","defaultTheme","blurCheckboxField","onGridClick","getWallPaperKeyFromTheme","backgrounds","uploadButton","colorButton","wallPapers","gridContainer","hasFile","isDark","dark","intensity","webkitMaskImage","_tempId","saveToCache","slug","hadSettings","getPixelPromise","imageUrl","imageSource","averageColorFromImageSource","averageColor","AppIncludedChatsTab","getContacts","foundInFilters","dialogsByFilters","onSelectChange","confirmBtn","editFolderTab","originalFilter","cmp","pinned_peers","other","otherLegacy","getInputPeerById","setFilter","onAppConfig","dialog_filters_chats_limit_premium","dialog_filters_chats_limit_default","categoriesSection","exclude_muted","ico","exclude_archived","exclude_read","selectedPeers","addedInitial","_add","AppEditFolderTab","deleteFolderButton","updateDialogFilter","menuBtn","inputSection","generateList","h2Text","includedFlagsContainer","excludedFlagsContainer","include","include_peers","editCheckForChange","reloadMissingPromises","reloadMissingPeerIds","onEditOpen","onCreateOpen","ignoreClick","hasPeer","renderMore","exclude_peers","purchaseUsernameCaption","purchaseText","setUsername","AppEditProfileTab","bioMaxLength","firstNameInputField","bioInputField","usernameInputField","isPurchase","availableText","takenText","invalidText","profilePromise","updateProfile","updateUsername","RIGHT_COLUMN_ACTIVE_CLASSNAME","AppSidebarRight","canHideFirst","isColumnProportionSet","toggleSidebar","setColumnProportion","createSharedMediaTab","replaceSharedMediaTab","previousTab","sharedMediaTab","historyTabIds","_selectTab","getFrom","setFrom","onCloseTab","isNavigation","willChange","appSidebarRight","AppEditContactTab","privacy","notificationsCheckboxField","profileNameDiv","profileSubtitleDiv","phoneRow","privacyRule","sharePhoneCheckboxField","btnDelete","deleteContacts","addContact","AppEditTopicTab","colorIndex","isGeneral","originalTopic","iconDiv","icon_emoji_id","setIcon","editForumTopic","topicId","iconEmojiId","createForumTopic","iconColor","emojiElement","icon_color","isMainIcon","newTopic","oldTopic","oldEl","applyFadeAnimation","fadeIn","iterations","easing","AppChatTypeTab","privateRow","publicRow","privateSection","publicContainer","chatUpdateListeners","basic","linkRow","btnRevoke","getChatInviteLink","publicSection","linkInputField","applyBtn","getValue","head","usernamesSection","getPeerEditableUsername","wasUsername","migrateChat","makeChannelPrivate","toggleNoForwards","onChatUpdate","noforwards","addChatUpdateListener","AppUserPermissionsTab","destroyListener","ChatPermissions","banned_rights","editBanned","btnDeleteException","clearChannelParticipantBannedRights","kickFromChannel","kickFromChat","defaultBannedRights","default_banned_rights","defaultRights","combineParticipantBannedRights","mediaNested","exceptionText","mediaToggleWith","mainFlag","embed_links","until_date","IGNORE_FLAGS","AppGroupPermissionsTab","chatPermissions","editChatDefaultBannedRights","addExceptionRow","openPermissions","getParticipant","setSubtitle","bannedRights","cantWhat","dialogDom","needAdd","new_participant","view_messages","prev_participant","exceptionsCount","setLength","setLoader","migrateFrom","migrateTo","AppChatReactionsTab","getActiveAvailableReactions","_chatReactions","available_reactions","chatReactions","makeReactionFromEmoticons","getCaptionLangPackKey","toggleSection","reactionsSection","toggleCheckboxFieldsByEmoticons","checkboxFieldsByEmoticon","toggleCheckboxField","toggleRow","saveReactionsDebounced","allow_custom","saveReactions","setChatAvailableReactions","isDebounced","AppEditChatTab","_init","canChangeType","canChangePermissions","canManageTopics","getCachedFullChat","chatNameInputField","descriptionInputField","chatTypeRow","setChatTypeSubtitle","availableReactionsLength","setReactionsLength","chatAvailableReactions","permissionsRow","setPermissionsLength","forum_upgrade_participants_min","topicsRow","setTopics","toggleForum","editTitle","editAbout","signMessagesCheckboxField","signatures","toggleSignatures","showChatHistoryCheckboxField","togglePreHistoryHidden","hidden_prehistory","historiesStorage","AppSharedMediaTab","newCloseBtn","animatedCloseIcon","transitionContainer","transitionFirstItem","titleI18n","editBtn","transitionLastItem","secondTitle","setIsSharedMedia","isSharedMedia","isHeavy","onCloseBtnClick","toggleEditBtn","deleteDeletedMessages","btnAddMembers","showConfirmation","addChatUser","_deleteDeletedMessages","setLoadMutex","peerChanged","changeTitleKey","loadSidebarMedia","destroyable","SetTransition","raf","afterTimeout","SidebarSlider","closeTab","closingId","onOpenTab","preserveTab","getTab","isTabExists","deleteTab","doNotAppend","SliderSuperTab","_constructor","SliderSuperTabEventable","dispatchResultableEvent","SortedUserList","getIndex","getUserStatusForSort","onDelete","onListLengthChange","willChangeLength","onElementCreate","base","updateElementWith","updateListWith","createChatListOptions","doTimeout","updateList","SORT_INTERVAL","AVATAR_CLASS_NAME","AVATAR_CONTAINER_CLASS_NAME","StackedAvatars","hasViewer","attachStickerViewerListeners","originalFindTarget","checkForParent","_middleware","previousTransformer","doThatSticker","lockGroups","isSwitching","effectThumb","mediaRect","fitted","aspectFitted","transformer","transformX","transformY","relativeEffect","loopEffect","firstFramePromise","prevPlayer","onMousePreMove","newMediaContainer","_previousTransformer","StickyIntersector","observeHeaders","observeElements","headersObserver","targetInfo","boundingClientRect","stickyTarget","rootBoundsInfo","rootBounds","threshold","elementsObserver","addSentinel","sentinel","headerSentinel","getEvent","getDistance","hypot","getTouchCenter","attachGlobalListenerTo","RESET_GLOBAL","TOUCH_MOVE_OPTIONS","MOUSE_MOVE_OPTIONS","WHEEL_OPTIONS","SwipeHandler","handleMove","setCursorTo","hadMove","releaseWheelDrag","releaseWheelZoom","resetValues","handleStart","isMouseDown","initialDistance","initialTouchCenter","verifyResult","withDelay","xDown","yDown","eventUp","onStart","xUp","yUp","xAdded","yAdded","setHadMove","endDistance","touchCenter","dispatchOnSwipe","handleWheel","is","onWheelCapture","onWheelZoom","handleWheelDrag","isDragCanceled","sign","initialDragOffset","dx","dy","wheelZoom","setCursor","onSwipeResult","TelInputField","pasted","lastValue","telEl","pixelRatio","letterSpacing","originalFunc","formattedPhoneNumber","leftPattern","TelegramWebView","onTelegramWebViewEvent","eventType","eventData","contentWindow","toastEl","hideToast","toastNew","transitions","navigation","prevTabContent","animateFirst","withAnimationListener","animationFunction","_animateFirst","onTransitionEndCallbacks","animationDeferred","listenerName","onEndEvent","overrideFrom","onTransitionEndCallback","transitionTimeout","_from","isUsernameValid","UsernameInputField","checkUsernameDebounced","checkUsername","checkUsernamePromise","checkPromise","available","UsernamesSection","_usernames","sortedList","editable","changeActive","applyUsernames","getAll","_peerId","cancelClick","newActive","toggleUsername","reorderUsernames","VisibilityIntersector","locked","change","refreshVisible","VolumeSelector","onMuteClick","setVolume","iconIndex","ICONS","wrapCustomEmoji","repeat","wrapCustomEmojiAwaited","wrapDocument","noAutoDownload","uploadFileName","extSplitted","ext","icoDiv","icoTextEl","hadContext","hasThumb","fileName","bytesContainer","descriptionParts","bytesMaxEl","sizeDiv","_downloadDiv","addByteProgress","sizeContainer","_bytesContainer","_d","canOpenAfter","downloadFileName","downloadId","isDownloading","support","was_online","dateEl","toggleMediaSpoiler","onMediaSpoilerClick","wrapMediaSpoilerWithImage","wrapMessageActionTextNew","plain","hadColors","wrapJoinVoiceChatAnchor","wrapLinkToMessage","dir","wrapSomeText","htmlToSpan","wrapTopicIcon","ns","contentSpan","gradientId","strokeColor","clone","topicAvatar","wrapMessageActionTopicIcon","wrapMessageActionTopicIconAndName","wrapMessageActionTextNewUnsafe","unsafeMessage","getNameDivHTML","post","schedule_date","daysToStart","tomorrowDate","_args","fetchMessageReplyTo","attach_menu","anchorHTML","isRecurringInit","recurring_init","isRecurringUsed","recurring_used","invoiceMessage","titleElement","authorElement","isMe","isIconChanged","isIconRemoved","isTitleChanged","isHiddenChanged","waited","wrapMessageForReply","hasAlbumKey","addPart","albumText","game","actionWrapped","noTextFormat","restriction_reason","exec","messageWrapped","wrapParticipantRank","wrapPeerTitle","wrapPhoto","noThumb","blurAfter","isImageFromDocument","isWebDoc","isFit","renderOnLoad","canAttachPreloader","haveToDownload","onlyCache","getDownloadPromise","wrapReply","setColorPeerId","wrapSenderToPeer","senderTitle","fromMe","wrapSentTime","STICKER_EFFECT_MULTIPLIER","locksUrls","videosCache","_timeout","wrapSticker","loadStickerMiddleware","exportLoad","asStatic","fullThumb","isCustomEmoji","syncedVideo","isEffect","stickerType","isAnimated","willHaveLock","lockUrl","toneIndex","isThumbNeededForType","lottieCachedThumb","getLottieCachedThumb","haveThumbCached","afterRender","getPathFromBytes","getPreviewURLFromThumb","stickerThumbConverted","webpWorkerController","saveWebPConvertedStrippedThumb","getImageFromStrippedThumb","middlewareError","sync","setLockColor","skipx","skipy","imageData","sr","sg","sb","sa","outCanvas","outContext","computeLockColor","onFirstFrame","saveLottiePreview","preloadAnimatedEmojiStickerAnimation","isSingleVideo","cacheName","framesCache","cachePromise","previousTime","playedTimes","onTimeupdate","mediaLength","lastPromise","_media","preloadSticker","playing","isAvailable","animationDiv","attachStickerEffectHandler","onEmojiStickerClick","getAnimatedEmojiSoundDocument","activeAnimations","emojiData","sendInteractionThrottled","interaction","withRandomOffset","onUnmount","wrapStickerAnimation","unmountAnimation","vibrate","generateRandomSigned","randomOffsetX","randomOffsetY","setPosition","factor","stableOffsetX","stableOffsetY","rectX","rectY","addOffsetX","addOffsetY","wrapStickerEmoji","wrapStickerSetThumb","downloadOptions","getStickerSetThumbDownloadOptions","getDocPromise","thumb_document_id","wrapStickerToRow","previousMedia","_size","wrapTopicNameButton","roundVideoCircumference","wrapVideo","isAlbumItem","canAutoplay","spanTime","spanPlay","needPlayButton","photoRes","divRound","halfSize","globalVideo","onPaused","onFrame","renderDeferred","loadPhotoThumbFunc","wrapWebPageDescription","shortDescriptionText","wrapWebPageTitle","shortTitle","EmojiVersions","Emoji","version","FontFamily","FontSize","FontWeight","instances","getAnimationInstance","cancelAnimationByKey","instance","isCancelled","animateSingle","tick","createAnimationInstance","AudioAssetPlayer","assets","playSound","createAudio","playSoundIfDifferent","stopSound","cancelDelayedPlay","playSoundWithTimeout","heavyQueue","processingQueue","addHeavyTask","processHeavyQueue","todo","possiblePromise","realResult","timedChunk","requireBlurPromise","fastBlurFunc","processBlurNext","dataUri","JPEG_HEADER","bytesFromHex","JPEG_TAIL","getPreviewBytesFromURL","needle","jpegBytes","atob","isSticker","convertToUint8Array","btoa","bytesToDataURL","imageW","imageH","boxW","boxH","noZoom","boxedImageW","boxedImageH","drawCircle","beginPath","closePath","drawCircleFromStart","measureText","createImageBitmap","resizeWidth","resizeHeight","badCharsRe","trimRe","C2L","clearBadCharsAndTrim","latinize","processSearchText","clearBadChars","hasTag","includeTag","charAt","originalText","ch","latinizeCh","latinizeString","fixCyrillic","fallbackCopyTextToClipboard","textArea","removeChild","copyTextToClipboard","clipboard","writeText","ContextMenuController","diffX","diffY","isOpened","openBtnMenu","days","ONE_DAY","getWeekNumber","UTC","dayNum","getUTCDay","setUTCDate","getUTCDate","yearStart","getUTCFullYear","formatDateAccordingToTodayNew","formatFullSentTimeRaw","formatTime","capitalize","textTransform","formatFullSentTime","getFullDate","monthAsNumber","noSeconds","leadingZero","noTime","minYear","yearPattern","monthYearOrDayPattern","yearOrDayAndMonthPattern","shortDate","longDate","numberOfDaysEachMonth","fillTipDates","dayOfWeek","formatWeekLong","getDayOfWeek","g1","g2","createForDayMonth","createForMonthYear","selectedYear","currentYear","g3","validDateForMonth","formatterYearMax","k1","formatterMonthYear","formatterDayMonth","T_ME","copyWhat","copyText","_cancelContextMenuOpening","_cancelContextMenuOpeningTimeout","cancelContextMenuOpening","onCancel","onMove","isTouch","onTouchEnd","touch","changedTouches","lastMouseDownElement","hasMouseMovedSinceDown","CLICK_EVENT_NAME","simulateClickEvent","ControlsHover","setHideTimeout","hideControlsTimeout","isShown","controlsLocked","toggleControls","relatedTarget","onBeforeOpen","disablePictureInPicture","resetCache","computedStyle","getProperty","getPropertyAsSize","simulateEvent","Event","tag","requestFullScreen","requestFullscreen","mozRequestFullScreen","webkitRequestFullscreen","msRequestFullscreen","cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen","msExitFullscreen","addFullScreenListener","addListener","eventName","getFullScreenElement","fullscreenElement","mozFullScreenElement","webkitFullscreenElement","msFullscreenElement","isFullScreen","getCaretPosF","childNodesLength","alt","markdownTags","entityName","underline","italic","monospace","strikethrough","mentionName","BLOCK_TAGS","BOM_REG_EXP","SELECTION_SEPARATOR","checkNodeForEntity","follow","isLineEmpty","getRichElementValue","selNode","selOffset","pushLine","isBlock","isTableCell","wasEntitiesLength","wasNodeEmpty","withEntities","withCaret","DocumentFragment","startOffset","startContainer","possibleChildrenFocusOffset","getCaretPos","overflowRect","foundVisible","lookForSticky","overflowTop","overflowRight","overflowBottom","overflowLeft","sticky","windowWidth","windowHeight","cancelY","onlyFull","commonAncestor","commonAncestorContainer","treeWalker","createTreeWalker","NodeFilter","SHOW_ELEMENT","SHOW_TEXT","acceptNode","intersectsNode","FILTER_ACCEPT","FILTER_REJECT","nextNode","resultBoolean","template","selectionRange","START_TO_END","isComposing","secondaryKey","isSwipingBackSafari","TouchEvent","ignoreTouchCheck","prevPos","backgroundImage","useCache","isImage","renderImageFromUrlPromise","compareNodes","node1","node1Offset","node2","node2Offset","NOT_ONLY_BOMS_REG_EXP","USING_BOMS","RichInputHandler","saveSelectionOnChange","saveRangeForElement","lastNode","lastOffset","setSelectionClassName","caret","getCaretPosN","move","superMove","getFiller","addInputCallback","processEmptiedFillers","fixInsertedLineBreaks","moveFirst","setEnd","isBOM","deleteData","processFilledFillers","removeEmptyTextNodes","fixBuggedCaret","savedRanges","IS_FIREFOX","inputCaptureCallbacks","anchorNode","findPreviousSmthIndex","something","fromSelectionChange","smthIndex","moved","idxidx","rangeString","onlyBOMs","restoreSavedRange","newCallback","sibling","needed","textNode","removePossibleBOMSiblings","removePossibleBOMSiblingsByNode","cleanSiblings","insertData","bomNode","focusNode","focusNodeBefore","focusOffset","focusOffsetBefore","collapseToStart","collapseToEnd","focusNodeAfter","focusOffsetAfter","fillers","smths","INSTANCE","keyframes","Sortable","elementRect","lastSiblings","getSortableTarget","scrollableRect","toEnd","addScrollPos","scrollPos","startScrollPos","isVertical","countNonElements","DropdownHover","onClickOut","ignoreButtons","ignoreMouseOut","toElement","willBeActive","inited","timeouts","setIgnoreMouseOut","onmouseout","onmouseover","FocusDirection","maxDistance","Static","scrollWithJs","rectStartKey","rectEndKey","sizeKey","scrollSizeKey","elementScrollSizeKey","scrollPositionKey","possibleElementPosition","containerSize","scrollSize","remainingPath","absPath","startAt","shortTransition","longTransition","currentPath","FILENAME_JOINER","getFileNameByLocation","thumb_size","big","stickerset","thumb_version","volume_id","local_id","strictDecimals","_decimals","dm","fixed","pow","parseFloat","CALL_DURATION_LANG_KEYS","mm","showLast","formatDuration","strings","prefixes","maxPrefixLength","setPrefix","originalStr","prefixCountry","patterns","searchForPattern","mostMatchedPatternMatches","mostMatchedPattern","_pattern","patternMatches","FramesCache","framesNew","framesURLs","getCache","createCache","releaseCache","getCacheCounter","generateName","arcParameter","rx","ry","xAxisRotation","largeArcFlag","sweepFlag","tl","tr","bl","useBlur","ignoreCache","ListLoader","loadedAllDown","unsetCurrent","toPrevious","goUnsafe","down","loadPromiseDown","loadPromiseUp","processedArr","processed","ListenerSetter","listeners","addManual","onceCallback","onceFired","_listener","isEnabled","MediaSize","aspect","aspectCovered","makeMediaSize","ScreenSize","CUSTOM_EMOJI_SIZE","ESG_CUSTOM_EMOJI_SIZE","EMOJI_STATUS_SIZE","MediaSizes","screenSizes","mobile","medium","large","handhelds","regular","album","esgSticker","documentName","extendedInvoice","customEmoji","esgCustomEmoji","popupSticker","desktop","isMobile","handleResize","innerWidth","activeScreen","wasScreen","throwWhat","numberThousandSplitter","HAVE_METADATA","useCanplayOnIos","loadEventName","errorEventName","OverlayClickHandler","withOverlay","useNative","isNegative","amountExp","exp","dec_point","thousands_sep","isFinite","prec","sep","dec","toFixedFix","number_format","decimal_sep","native","splitter","additionalPadding","getScrollWidthFromElement","menuWidth","menuHeight","paddingBottom","maxTop","maxLeft","minLeft","intermediateX","intermediateY","possibleSides","platforms","getRestrictionReason","reasons","savingLottiePreview","isSavingLottiePreview","saving","throttleWithRaf","fn","schedulerFn","waiting","throttleWith","ScrollSaver","findElements","findAndSetElements","_save","scrollHeightMinusTop","onRestore","useReflow","setScrollTop","newScrollTop","_restore","previousScrollHeightMinusTop","ScrollableLoader","SearchListLoader","filterMids","onHistoryDelete","shouldBeDeleted","onHistoryMultiappend","isInner","otherSideLoader","filterMessagesByInputFilterFromStorage","goToOtherEnd","do","kind","scheduleFlush","measure","mutate","mutateElement","read","write","pushDocumentSize","_isWebDocument","comments","BatchProcessor","setQueue","renderedQueue","SortedList","_updateList","canUpdate","createPromise","noScheduler","encodeEntities","limitFrom","leadZero","sec_num","hours","minutes","seconds","textToSvgURL","reader","FileReader","readAsDataURL","visualViewport","innerHeight","ANIMATION_START_EVENT","ANIMATION_END_EVENT","isAnimating","heavyAnimationPromise","promisesInQueue","dispatchHeavyAnimationEvent","_heavyAnimationPromise","onHeavyAnimationEnd","interruptHeavyAnimation","getHeavyAnimationPromise","handleAnimationStart","handleAnimationEnd","DialogsContextMenu","onArchiveClick","editPeerFolders","folder_id","onHideTopicClick","onToggleTopicClick","toggleDialogPin","onUnmuteClick","onUnreadClick","top_message","getButtons","getDeleteButtonText","lastButton","isDialogUnread","ConnectionStatusComponent","hadConnect","connecting","timedOut","updating","setConnectionStatus","overrideStatus","baseDcId","connectionStatus","setFirstConnectionTimeout","online","forceGetDifference","retryAt","setStatusText","currentLangPackKey","statusEl","statusPreloader","singleInstance","CHANGE_STATE_DELAY","getA","networkerFactory","forceReconnect","timerSpan","interval","forceReconnectTimeout","setStateTimeout","statusContainer","SENDING_STATUS","easeInOutSine","easeInOutSineApply","roundRect","defaultRadius","moveTo","lineTo","quadraticCurveTo","DPR","SIZE","MARGIN","WIDTH","RADIUS","Shimmer","currTime","diffTime","spread","pausedTime","pauseInterval","lightSource","lightSpread","currentAnimationIndex","keepTime","cycleAnimation","currentAnimation","animateGlow","animateSlide","smartInc","lightLeft","lightRight","lightCenter","createLinearGradient","shimmerColor","addColorStop","dict","on","fillText","DialogsPlaceholder","onThemeChange","stopAnimation","startAnimation","updateCanvasSize","shimmer","generatedValues","marginVertical","lineBorderRadius","lineMarginVertical","statusWidth","getRectFrom","onRemove","blockScrollable","overflowY","availableLength","detachTime","renderDetachAnimationFrame","globalCompositeOperation","completed","elapsedRowTime","dialogHeight","renderFrame","createPattern","patternCanvas","patternContext","drawChat","firstLineWidth","secondLineWidth","marginLeft","setPromiseMiddleware","oldPromise","SortedDialogList","getDialogIndex","forumPeerId","indexKey","addListDialog","isBatch","isMainList","DialogElement","bigger","abitbigger","small","captionDiv","titleSpanContainer","peerTitlePromise","statusSpan","lastTimeSpan","rightSpan","setDialogActive","forumTab","createUnreadBadge","unreadBadge","badge","createUnreadAvatarBadge","unreadAvatarBadge","createMentionsBadge","mentionsBadge","toggleBadgeByKey","hasBadge","justCreated","ForumTab","init2","isFloating","toggleForumTab","createChatList","setListClickListener","xd","Some3","bindScrollable","getOptionsForMessages","fullReset","setStatusPromise","noTyping","onChatsScroll","loadResult","setStatus","NOT_IMPLEMENTED_ERROR","Some","onChatsRegularScroll","sliceTimeout","processContact","scrollTopWas","rectContainer","rectTarget","firstY","lastY","firstElement","elementFromPoint","lastElement","elementOverflow","sliceFromStart","sliceFromEnd","deleteDialogByKey","getDialogKeyFromElement","setOffsets","offsets","getOffsetIndex","isDialogMustBeInViewport","topOffset","bottomOffset","setIndexKey","deleteDialog","getDialogKey","updateDialog","loadedDialogsAtLeastOnce","getDialogElement","setLastMessageN","setUnread","onChatsScrollTop","loadDialogs","createPlaceholder","placeholderOptions","getRectFromForPlaceholder","loadDialogsPromise","loadDialogsRenderPromise","cachedInfoPromise","chatList","getConversationsResult","loadDialogsInner","needPlaceholderAtFirstTime","isTopEnd","offsetDialog","firstDialog","lastDialog","getDialogFromElement","getDialogDom","oldTypingElement","newTypingElement","unsetTyping","paddingX","typings","topics","setUnreadMessagesN","drop","sidebarRect","currentOffsetIndex","needIndex","Some2","getUserStatus","setOnlineStatus","processDialogForCallStatus","validateDialogForFilter","getCachedDialogs","validateListForFilter","doNotRenderChatList","hasClassName","generateScrollable","getDialogIndexKey","sortedDialogList","testDialogForFilter","migratedTo","setCallStatus","callIcon","START_X","wasMounted","itemProgress","groupCallActiveIcon","call_active","call_not_empty","loadContacts","toggleAvatarUnreadBadges","sortedDialog","reuseClassNames","unreadContent","isUnreadAvatarBadgeMounted","unreadAvatarBadgeClassList","unreadBadgeClassList","AppDialogsManager","Log","menuScrollContainer","lastActiveElements","initedListeners","xds","onTabChange","_onListLengthChange","checkIfPlaceholderNeeded","hasContacts","removeContactsPlaceholder","updateContactsLength","verifyPeerIdForContacts","getProxiedManagers","stateMiddlewareHelper","bottomPart","forumsTabs","forumsSlider","allChatsIntlElement","isFilterIdAvailable","clearCurrent","showFiltersPromise","onStateLoaded","setFilterId","addFilter","foldersScrollable","_id","filtersNavigationItem","setFilterIdAndChangeTab","changeFiltersAllChatsKey","groupCallsController","callsController","initListeners","setFiltersUnreadCount","setFilterUnreadCount","elementThreadId","elementPeerId","onFiltersLengthChange","containerToAppend","getDialogIndexKeyByFilterId","renderedFilter","filtersArr","haveFilters","addFilters","addFiltersPromise","getNotifyPeerTypeSettings","fillConversations","unreadSpan","unreadUnmutedCount","unreadCount","getFolderUnreadCount","wasShowing","generateEmptyPlaceholder","classNameType","subtitleArgs","placeholderContainer","emptyDialogsPlaceholderSubtitle","usersLength","placeholderType","updatePartClassName","updateContactsLengthPromise","newTab","hideTab","forumNavigationItem","toggleForumTabByPeerId","lastTab","isSameTab","withContext","openInner","lastActiveListElement","setPeerFunc","setLastMessage","draftMessage","isSearch","isMessageRestricted","willPrepend","videoTypes","playIcon","replyTo","forum_topic","setUnreadMessages","isDialogPinned","getForumUnreadCount","hasUnmuted","isPinned","forumUnreadCount","wasMuted","unreadTopicsCount","hasUnmutedTopic","setStatusMessage","read_inbox_max_id","hasUnreadBadge","hasUnreadAvatarBadge","disableAnimationIfRippleFound","iconClassName","setSendingStatus","isUnreadBadgeMounted","hasMentionsBadge","isMentionsBadgeMounted","isBadgeMounted","unreadBadgeText","isMention","notVisited","getDialog","originalDialog","addDialogNew","addDialogAndSetLastMessage","getMessageSenderPeerIdOrName","downloads","getNewDeferred","cancelDownload","clearDownload","getNewDeferredForUpload","getUpload","getDownload","getUploadPromise","getDownloadFileNameFromOptions","downloadMedia","promiseBefore","getDownloadMediaDetails","downloadMediaURL","downloadMediaVoid","getFileNameForUpload","downloadToDisc","justAttach","pingPromise","hadProgress","getDocumentDownloadOptions","getPhotoDownloadOptions","clickEvent","createEvent","initMouseEvent","createDownloadAnchor","CLASSNAME_BASE","PinnedContainer","floating","divAndCaption","wrapperUtils","attachOnCloseEvent","needClose","setFloating","setUtilsWidth","ChatAudio","onPlaybackParams","fasterEl","repeatEl","toggleEl","onStop","onMediaPlay","isMusic","prevEl","nextEl","attachClick","volumeProgressLineContainer","tunnel","progressWrapper","playingDetails","BAR_HEIGHTS","PinnedMessageBorder","drawRect","getClipPath","barHeight","GAP","clipPath","getBarHeight","ONE","TWO","THREE","FOUR","MORE","getMarkHeight","markHeight","getMarkTranslateY","getTrackTranslateY","trackHeight","getTrackHeight","clipPathId","markTranslateY","trackTranslateY","mark","AnimatedSuper","getRow","clearRow","clearRows","currentIndex","DURATION","setNewRow","reflow","previousIndex","fromTop","ignorePrevious","previousRow","AnimatedCounter","previousNumber","getDecimal","animatedSuper","decimal","hideLeft","previousDecimalNumber","EMPTY_INDEX","setCount","previousByDecimal","decimalNumber","ChatPinnedMessage","pinnedMaxMid","pinnedMid","pinnedIndex","wasPinnedIndex","wasPinnedMediaIndex","waitForScrollBottom","loadedBottom","loadedTop","scrollDownListenerSetter","getCurrentIndexPromise","isStatic","dAC","pinnedMessageBorder","animatedSubtitle","animatedMedia","animatedCounter","btnOpen","openPinned","setPinnedMessage","_setPinnedMessage","unsetScrollDownListener","testMid","isNeededMore","getCurrentIndex","LOAD_OFFSET","correctAfter","gotRest","getPinnedMessage","backLimited","offset_id_offset","setScrollDownListener","isDown","handleScrollSideEvent","refreshPosition","handleFollowingPinnedMessage","followPinnedMessage","writeTo","writeMediaTo","ChatTopbar","verifyButtons","isMenuOpen","btnMore","buttonsToVerify","menuButtons","verifyVideoChatButton","currentGroupCall","groupCall","verifyCallButton","getCachedFullUser","phone_calls_available","video_calls_available","onJoinGroupCallClick","joinGroupCall","resize","setUtilsRAF","chatUtils","chatAudio","setPeerStatusManual","btnBack","btnBackBadge","chatInfoContainer","chatInfo","person","avatarElement","deleteButtonText","btnJoin","btnPinned","btnCall","btnGroupCall","btnMute","btnSearch","pushButtonToVerify","onBtnBackClick","isFirstChat","constructUtils","linked_chat_id","onCallClick","chatContextMenuHintWasShown","contactPeerId","getAttachMenuBot","has_settings","constructAvatar","joinChannel","unreadUnmutedPeerIds","setMutedState","isTopMessage","hiddenPinnedMessages","byCurrent","setTitleCallback","setStatusCallback","setTitleManual","canHaveSomeButtons","wasAlreadyUsed","newPinnedMessage","AppPrivateSearchTab","appSearch","btnPickDate","ChatSearch","selectedIndex","onResultsClick","selectResult","onFooterClick","onUpClick","onDownClick","foundCountEl","upBtn","downBtn","footer","dateBtn","renderedCount","ChatBackgroundPatternRenderer","canvases","INSTANCES","renderToCanvas","fillCanvas","crossOrigin","imageBitmap","objectUrl","imageWidth","imageHeight","patternHeight","mask","topY","endY","bottomY","setCanvasDimensions","originalHeight","Chat","backgroundEl","backgroundTempId","sharedMediaTabs","setBackground","patternRenderer","gradientCanvas","previousGradientRenderer","previousPatternRenderer","previousPatternCanvas","isDarkPattern","getInstance","_gradientRenderer","setOpacityTo","opacityMax","setBackgroundPromise","setType","freezeObservers","APP_TABS","CHAT","beforeDestroy","cleanupBackground","destroySharedMediaTab","searchTab","_isAnyGroup","setAutoDownloadMedia","getForumTopicOrReload","isSamePeer","bubblesSetPeerPromise","photoSizeMax","videoSizeMax","fileSizeMax","photo_size_max","video_size_max","file_size_max","getAutoDownloadSettingsByPeerId","callbacksPromise","ignoreThreadId","historyStorageTransferable","historySerialized","updateStickersetOrder","MarkupTooltip","waitingForMouseUp","mouseUpCounter","onMouseUpSingle","resetSelection","tools1","tools2","cancelClosening","linkBackButton","linkInput","applyLink","isLinkValid","setTooltipPosition","linkApplyButton","applyDiv","delimiter1","delimiter2","delimiter3","matchUrlProtocol","getActiveMarkupButton","currentMarkups","markup","activeButtons","isLinkToggle","bodyRect","selectionRect","inputRect","selectionTop","sizesRect","isFirstShow","setMouseUpEvent","handleSelection","ChatDragAndDrop","dropIcon","onDragOver","onDragLeave","onDrop","outlineWrapper","dropHeader","dropSubtitle","headerArgs","setPath","sizeX","sizeY","disableTransition","LineBlobDrawable","maxRadius","minRadius","N","radiusNext","speed","generateBlob","radDif","generateNextBlob","amplitude","speedScale","paint","pinnedTop","progressToPinned","r1","progressNext","x2","cx","y2","bezierCurveTo","WeavingState","stateId","createGradient","shader","getGradientFromType","x0","y0","dt","TopbarWeave","handleDevicePixelRatioChanged","setSize","forceUpdate","resizeHandler","resizeCanvas","invokeDraw","handleFocus","focused","handleBlur","lbd","lbd1","lbd2","currentState","previousState","progressToState","lastUpdateTime","animateToAmplitude","animateAmplitudeDiff","amplitude2","animateAmplitudeDiff2","top1","top2","paint1","setCurrentState","states","componentDidMount","matchMedia","setAmplitude","componentWillUnmount","setCanvasSize","RLottieIconItemPart","playPart","RLottieIconItem","createPart","initFrame","skipFirstFrameRendering","inverseColor","onLoadForColor","onLoadForPart","getPart","RLottieIcon","startFrame","endFrame","frameCount","SuperRLottieIcon","partState","colorState","getColor","partCallback","changedPartState","changedColorState","setPartState","setColorState","prevState","renderIfPaused","invoke","GroupCallMicrophoneIcon","GROUP_CALL_MICROPHONE_BUTTON_STATE","partName","HAND","MUTED","UNMUTED","GroupCallParticipantMutedIcon","colored","GROUP_CALL_PARTICIPANT_MUTED_STATE","colorStr","MUTED_FOR_ME","MUTED_BY_ADMIN","propertyValue","getColorByMutedState","generateEqualParts","clearMutedStateModifier","GroupCallParticipantStatusElement","element2","actionClassName","GroupCallParticipantsList","getParticipantByPeerId","onElementDestroy","getGroupCallParticipantMutedState","mutedIcon","callVideoCanvasBlur","GroupCallParticipantVideoElement","setPinned","setParticipant","groupCallParticipantMutedIcon","groupCallParticipantStatus","updateParticipant","GroupCallParticipantsVideoElement","participantsElements","groupCallId","setElementDisplay","pinnedSource","pinSource","unpinAll","setInstance","shouldDisplayElement","displayPinned","shouldDisplay","hasAnyVideo","participantElements","participantVideo","getVideoElementFromParticipantByType","_onLengthChange","GroupCallParticipantContextMenu","onOpenProfileClick","PopupGroupCall","targetPeerId","toggleParticipantMuted","editParticipant","canManageCall","can_self_unmute","muted_by_you","getContainer","GroupCallParticipantsElement","groupCallParticipantsVideo","appGroupCallsManager","getGroupCallParticipants","GroupCallDescriptionElement","descriptionIntl","GroupCallTitleElement","makeButton","_className","buttonDiv","isConfirm","resizeHandlerClassName","MovableElement","fixDimensions","fixPosition","addResizeHandlers","setSwipeHandler","destroyElements","handlers","startTop","startLeft","startWidth","startHeight","resizingSide","isEnlarging","resizeDiff","maxPossible","setPositionToCenter","MovablePanel","toggleMovable","movable","movableOptions","toggleClassName","raise_hand_rating","onFullScreenClick","onToggleControls","buttonsContainer","onVideoClick","btnVideo","toggleVideoSharing","onScreenClick","btnScreen","toggleScreenSharing","toggleMuted","changeRaiseHand","onLeaveClick","hangUp","discard","toggleBigLayout","btnFullScreen","btnExitFullScreen","wasFullScreen","movablePanel","videosCount","wasBig","btnInvite","btnShowColumn","toggleRightColumn","btnFullScreen2","headerInfo","newHeader","newHeaderInfo","newHeaderTitle","btnHideColumn","videosScrollable","groupCallTitle","groupCallDescription","groupCallBodyHeaderDescription","constructButtons","groupCallParticipants","updateInstance","setHasPinned","groupCallMicrophoneIcon","_makeButton","microphoneIcon","btnLeave","setDescription","microphoneButtonState","getGroupCallMicrophoneButtonState","micState","CallDescriptionElement","connectionState","connectedAt","GroupCallMicrophoneIconMini","INIT_STATE","PopupCall","resizeVideoContainers","videoContainers","interlocutorUserId","emojisSubtitle","partyStates","partyMutedState","stateText","constructFirstButtons","constructSecondButtons","wasTryingToJoin","movableElement","controlsHover","getCallInstance","firstButtonsRow","muteI18nElement","secondButtonsRow","declineI18nElement","btnDecline","btnAccept","acceptCall","createVideoContainer","isPendingIncoming","isSharingVideo","isSharingScreen","outputState","getMediaState","oldContainers","mediaState","getVideoElement","hasFrame","hasPromise","videoState","screencastState","videoContainer","output","getEmojisFingerprint","popupWidth","MAX_WIDTH_PX","MAX_HEIGHT_PX","MAX_SIZE","biggestSideSize","widthRatio","heightRatio","TopbarCall","onState","amplitudes","weave","clearCurrentInstance","currentDescription","instanceListenerSetter","isChangingInstance","callDescription","convertCallStateToGroupState","groupCallMicrophoneIconMini","throttledMuteClick","weaveContainer","uiNotificationsManager","notificationsShown","notificationIndex","notificationsCount","soundsPlayed","vibrateSupport","faviconElements","titleBackup","titleChanged","stopped","pushInited","updateLocalSettings","updSettings","nodesktop","novibrate","nopreview","nopush","needPush","webPushApiManager","registeredDevice","nosound","requestPermission","Notification","mozVibrate","webkitVibrate","setAppBadge","notificationsUiSupport","notifySoundEl","topMessagesDeferred","toggleToggler","peerString","soundReset","tokenData","unregisterDevice","registerDevice","notificationData","custom","hasChat","hasUser","buildNotification","fwdCount","peerReaction","peerTypeNotifySettings","notification","getPeerString","notificationMessage","wrappedMessage","noIncrement","peerTitleOptions","notificationFromPeerId","peerPhoto","loadAvatar","avatarCanvas","avatarContext","avatarGradients","colorTop","colorBottom","abbreviation","getAbbreviation","textBaseline","textAlign","pushData","loc_key","loc_args","resetTitle","isBlink","setFavicon","titleInterval","prevFavicon","testSound","permission","notificationOptions","registration","serviceWorker","showNotification","getNotifications","appRuntimeManager","onclose","getLocalSettings","closeNotification","nextSoundAt","prevSoundVolume","filename","token_type","tokenType","tokenValue","other_uids","app_sandbox","secret","getFilesFromEvent","onlyTypes","scanFiles","isDirectory","directoryReader","createReader","readEntries","itemFile","getAsFile","DataTransferItem","DragEvent","dataTransfer","webkitGetAsEntry","addAnchorListener","protocol","noCancelEvent","pathnameParams","uriParams","u","host","noPathnameParams","noUriParams","parseUriParams","PopupGiftPremium","giftOptions","shortestOption","wrapCurrency","giftOption","shortestAmount","discount","getSelectedOption","giftButton","bot_url","AppImManager","columnEl","offline","updateStatusInterval","cacheStorage","saveState","onHashChangeUnsafe","tgaddr","openUrl","postId","openUsername","userName","setSettings","messagesTextSize","forceRenderAfterSize","chatsSelectTabDebounced","changedLoop","changedAutoplay","toggleChatGradientAnimation","onDocumentPaste","attachType","newMediaPopup","_types","canDrag","backgroundPromises","CHATLIST","updateStatus","emojiAnimationContainer","appendEmojiAnimationContainer","createNewChat","chatsSelectTab","getPremium","compareVersion","deleteFilesIterative","applyCurrentTheme","resizeInstances","saveChatPosition","choosing","setChoosingStickerTyping","typing","onInstanceDeactivated","isUpdated","receiptMessage","onSpoilerClick","spoilerTimeout","mediaStickerWrapper","playOrRestart","stateStorage","topbarCall","discardCurrentCall","currentCall","setAuthorized","telegramMeWebManager","hashtag","makeLink","thread","channel","comment","getStackFromElement","nestedLink","startattach","attachKeydownListener","handleAutologinDomains","checkForShare","share","foundMedia","openWindow","onUrlAuthResult","urlAuthResult","botPeerTitle","logInCheckbox","allowMessagesCheckbox","request_write_access","confirmationPromise","logInChecked","allowMessagesChecked","acceptUrlAuth","onUrlAuthResultAccepted","requestUrlAuth","config","_appConfig","_config","onAnchorClick","url_auth_domains","autologinToken","autologin_token","autologin_domains","originalUrl","searchParams","possibleBubble","timeoutOperation","requests","request","isBad","activatingChat","screen","IGNORE_KEYS","isSelectionCollapsed","isTargetAnInput","getFirstMessageToEdit","getNextDialog","newEvent","KeyboardEvent","commentId","resolveChannel","op","checkChatInvite","saveApiChat","resolvePhone","getInputInvoiceBySlug","botUsername","resolveUserByUsername","errorLangPackKey","bot_attach_menu","haveWriteAccess","toggleBotInAttachMenu","wrappedUrl","openComment","openPremiumBot","premium_bot_username","generateThreadServiceStartMessage","phone_calls_private","ignoreGroupCall","ignoreCall","discardGroupCallConfirmation","discardCallConfirmation","title1","title2","isClosing","getGroupCallFull","createGroupCall","setCurrentBackground","broadcastEvent","getBackground","getFile","lastBackgroundUrl","chatBubbles","chatPositions","backgroundUrl","attachDragAndDropListeners","drops","mediaDrops","isFiles","_dropsContainer","mediaDropsContainer","dropsContainer","_drops","foundDocuments","PROFILE","onImTabChange","updateMyOnlineStatus","spliceChats","fromIndex","chatFrom","chatTo","chatIndex","existingIndex","oldChat","getTypingElement","eye","getPeerTyping","getPeerTypings","langPackKeys","multi","mapa","typingElement","descriptionElement","getChatStatus","typingEl","onlines","getOnlines","getPeerStatus","typingContainer","options1","options2","premium_gifts","INTERNAL_LINK_TYPE","onlyInner","DialogColorsFg","DialogColors","DialogColorsMap","pic","peerParams","useBytes","bestPhotoSize","CallConnectionInstanceBase","connection","sources","createPeerConnection","RTCPeerConnection","signalingState","iceConnectionState","createDataChannel","dataChannel","createDescription","appendStreamToConference","streamManager","appendToConference","closeConnection","closeConnectionAndStream","stopStream","negotiate","negotiating","negotiateInternal","sendDataChannelData","parseSignalingData","sdp","parseMediaSectionInfo","fingerprint","ufrag","pwd","convertNumber","isSending","codec","ssrc","sourceGroups","ssrcGroups","sourceGroup","semantics","ssrcs","rtpExtensions","payloadTypesMap","getPayloadType","payloadType","clockrate","feedbackTypes","subtype","parameters","payloadTypes","CallConnectionInstance","localDescription","remoteDescription","descriptionInit","offerReceived","createAnswer","setLocalDescription","offer","createOffer","offerSent","initialSetup","sendCallSignalingData","crypto","subtle","P2PEncryptor","p2pKey","seqMap","concatSHA256","bufferConcats","encryptPrepared","msgKeyLarge","subarray","msgKey","aesKeyIv","prepareAesKeyIv","aesProcessCtr","encryptRawPacket","seq","ArrayBuffer","setUint32","sha256a","sha256b","iv","encryptedData","dataSize","encrypt","cryptoKey","constTimeIsDifferent","msgKeyEquals","decryptRawPacket","encryptedDataSize","decryptionBuffer","getUint32","ChromeP2PSdpBuilder","fingerprints","stringBuilder","streamName","addExtmap","addPayloadTypes","addSsrc","finalize","FirefoxP2PSdpBuilder","SafariP2PSdpBuilder","isFirefox","isSafari","extmap","j","fmtp","getOwnPropertyNames","pName","ssrcGroup","P2PSdpBuilder","sdpString","sdpMLineIndex","sdpMid","foundation","component","priority","relAddress","generation","tcpType","networkId","networkCost","candidate","generateOffer","generateAnswer","CallInstance","udp_p2p","udp_reflector","min_layer","max_layer","library_versions","createdAt","decryptQueue","candidates","canCreateConferenceEntry","setMediaState","sendMediaState","mediaStates","_sendMediaState","_connectionState","connectionInstance","sortIndex","findEntry","recvEntry","startScreenSharingInternal","wasStartingScreen","wasStartingVideo","requestScreen","stopVideoSharing","startVideoSharingInternal","requestInputSource","track","inputStream","getVideoTracks","stopTrack","isSharingVideoType","audioTrack","getAudioTracks","setHangUpTimeout","clearHangUpTimeout","hangUpTimeout","setPhoneCall","phoneCall","canAccept","overrideConnectionState","g_a_hash","appCallsManager","generateDh","dh","g_b","g_a","g_b_hash","getCallInput","phonePhoneCall","savePhonePhoneCall","joinCall","encryptionKey","configuration","iceServers","connections","ipv6","port","urls","turn","stun","credential","iceTransportPolicy","p2p_allowed","getRtcConfiguration","sendIceCandidate","onTrack","encryptor","decryptor","processDecryptQueue","createDataChannelEntry","dataChannelEntry","createEntry","sendEntry","negotiated","applyDataChannelData","TextEncoder","encode","iceCandidate","parsed","p2pParseCandidate","confirmCall","key_fingerprint","computeKey","emojisFingerprint","getEmojisFingerprintPromise","codePoints","unlockStreamManager","doTheMagic","getTransceivers","transceiver","getEntryByMid","bundle","sdpDescription","generateSdp","isAnswer","setRemoteDescription","onInputStream","stream","videoTrack","onMutedChange","requestAudioSource","setMuted","discardReason","discardedByOtherParty","hasVideo","discardCall","performCodec","_codec","setDataToDescription","setData","transport","screencast","filterNotVP8","vp8PayloadType","rtxIdx","apt","applyCallSignalingData","performSsrcGroups","getEntryBySource","sendRecvEntry","findFreeSendRecvEntry","setEntrySource","tryToReleaseCandidates","generateCandidate","RTCIceCandidate","addIceCandidate","decryptedData","TextDecoder","decode","signalingData","onUpdatePhoneCallSignalingData","getStreamCached","_cache","isScreen","constraints","getScreenStream","getStream","CallInstanceBase","fixSafariAudio","isSharingAudio","hasInputTrackKind","isAudioGood","isVideoGood","getAudioConstraints","getVideoConstraints","getScreenConstraints","endpoint","tryAddTrack","streams","saveInputVideoStream","isOutput","elementEndpoint","addTrack","useStream","outputStream","srcObject","sinkId","outputDeviceId","setSinkId","getTracks","addStream","CALL_STATE","audioAsset","CALL_REQUEST_TIMEOUT","CallsController","sortedInstances","createCallInstance","admin_id","g_a_or_b","bytesCmp","callId","getCallByUserId","hasConnected","hasCurrent","startCallInternal","fullInfo","participant_id","requestCall","GROUP_CALL_AMPLITUDE_ANALYSE_COUNT_MAX","GROUP_CALL_AMPLITUDE_ANALYSE_INTERVAL_MS","GroupCallConnectionInstance","negotiateThrottled","bundlePolicy","rtcpMuxPolicy","iceCandidatePoolSize","maybeUpdateRemoteVideoConstraints","updateConstraintsInterval","invokeJoinGroupCall","localSdp","mainChannels","processedChannels","sectionInfo","payload","processMediaSection","audioChannel","videoChannel","useChannel","setEntryPeerId","performExtmap","filterServerCodecs","isNewConnection","originalOffer","iceRestart","hasMunged","skipAddingMulticast","mediaLine","mediaLineParts","localMLine","codecIds","newData","setPort","setSource","newSdp","addSsrcEntry","newChannel","mungedSdp","fixLocalOffer","entriesToDelete","shouldBeSkipped","answerDescription","deleteEntry","iceGatheringState","updateConstraints","sender","setParameters","getParameters","degradationPreference","colibriClass","defaultConstraints","onStageEndpoints","addInputVideoStream","GroupCallInstance","isSpeakingMap","pinnedSources","participantsSsrcs","hadAutoPinnedSources","dispatchPinnedThrottled","getCachedParticipants","presentation","unpinSource","changeUserMuted","source_groups","createConnectionInstance","raise","raiseHand","stopScreenSharing","startScreenSharing","startScreenSharingPromise","saveApiParticipant","leaveGroupCallPresentation","videoPaused","videoStopped","startVideoSharing","startVideoSharingPromise","rejoin","isDiscarded","isUpdatingMeInCurrentCall","onParticipantUpdate","doNotDispatchParticipantUpdate","hasLeft","oldSsrcs","modifiedTypes","oldSsrc","oldSource","oldEntry","originalDirection","setEndpoint","createTransceiver","GROUP_CALL_STATE","makeSsrcsFromParticipant","makeSsrcFromParticipant","audio_source","generateSelfVideo","audioSource","GroupCallsController","setCurrentGroupCall","startConnectingSound","stopConnectingSound","joinVideo","MediaStream","createMainStreamManager","joinGroupCallInternal","handleUpdateGroupCallParticipants","updatingSdp","channelCount","constraint","mediaDevices","getSupportedConstraints","constraintSupported","skipAudio","frameRate","screenStream","getDisplayMedia","contentHint","getUserMedia","clientInfo","lookupAttributeKeys","telegramSourceGroups","sdpLines","rest","parseSourceGroups","raw","ConferenceEntry","addTransceiver","generateSsrc","LocalConferenceDescription","sessionId","maxSeenId","entriesByMid","entriesBySource","entriesByPeerId","getEntriesByPeerId","conference","SDP","mediaSections","splitStringByLimitWithRest","UniqueNumberGenerator","generate","maxTries","_try","SDPAttributeSplitted","SDPMediaLineParts","SDPLine","SDPAttributeInner","missed","exists","nestedMap","makeAttributes","innerParts","SDPAttributes","fillAttributes","attributesMap","linesArray","SDPMediaSection","isReceiving","resultShouldBeArray","SDPSessionSection","parseSdp","createSection","sessionSection","lineStr","isIncorrectSdpLine","parseSdpLine","addSimulcast","generator","originalSsrcs","ssrcs2","ssrcsStrLines","ssrc2","WEBRTC_MEDIA_PORT","fixMediaLineType","getConnectionTypeForMediaType","generateMediaFirstLine","payloadIds","connectionType","SDPBuilder","addCandidate","performCandidate","addHeader","sId","bundleMids","addTransport","skipCandidates","addSource","addMsid","isApplication","isInactive","hdrexts","hdrext","fbs","fb","addConference","AudioStreamAnalyser","streamSource","createMediaStreamSource","gain","createGain","minDecibels","maxDecibels","smoothingTimeConstant","StreamManager","getAmplitude","streamAnalyser","analyse","ANALYSER_LISTENER","AudioContext","webkitAudioContext","getSource","itemSource","removeTrack","finalizeAddingTrack","changeTimer","substring","replaceInputAudio","oldTrack","timer","transceiverInit","tracks","mediaTrackType","trackIdx","replaceTrack","StringFromLineBuilder","newLine","addJoined","toTelegramSource","fromTelegramSource","rms","SEND_WHEN_ONLINE_TIMESTAMP","EMOJI_REG_EXP","onlyFirst","firstEmojiMatch","lastEmojiMatch","E","setBlankToAnchor","messageEntityTextUrl","messageEntityMentionName","isDraft","EMOJI_VERSIONS_SUPPORTED","inlineEl","newEmojiWidth","legacyEmojiWidth","isEmojiSupported","globalLazyLoadQueue","CustomEmojiElement","syncedPlayer","pausedElements","playersSynced","createCustomFiller","lastPausedVideo","middlewares","CustomEmojiRendererElement","clearedElements","WeakSet","isCanvasClean","emojiRenderers","getOffsets","offsetsMap","offsetParent","elementsArr","placeholders","isDimensionsSet","syncedPlayersFrames","isImageData","ImageData","frameWidth","frameHeight","lastChildWas","checkForAnyFrame","forceRenderAfter","renderEmojis","addCustomEmojis","addElements","usingOwnQueue","_loadPromises","newElements","isLottie","willHaveSyncedPlayer","newElementsArray","CUSTOM_EMOJI_INSTANT_PLAY","addition","_p","overrideRender","setRenderInterval","syncedPlayers","clearRenderInterval","missing","cachedPromises","uncachedPromisesPromise","loadFromPromises","uncached","emojiRenderInterval","renderers","nasty","usedLength","wrapSomething","wrapElement","noFiller","customWraps","contextSite","contextExternal","lastEntity","nextEntity","endPartOffset","fullEntityText","partText","usedText","fontFamily","atPos","fromBot","encodeURIComponent","isSupported","masked","currentContext","electronHelpers","contextUrl","wrapTelegramUrlToAnchor","encoded","encodeSpoiler","entityText","voodoo","insertCustomFillers","notFiller","isCustomFillerNeededBySiblingNode","url1","QueryableWorker","worker","terminate","onmessage","queryMethodListener","queryMethodArguments","postMessage","sendQuery","transfer","queryMethod","workersLimit","playersByCacheName","workers","curWorkerNum","onPlayerLoaded","reqId","fps","clamped","onPlayerError","getAnimation","loadLottieWorkers","remain","Worker","queryableWorker","makeAssetUrl","loadAnimationAsAsset","loadAnimationFromURL","loadAnimationDataFromURL","blobConstruct","loadAnimationFromURLManually","loadAnimationFromURLNext","newParams","loadAnimationWorker","waitForFirstFrame","initPlayer","destroyWorkers","loadFromData","getLottiePixelRatio","RLottiePlayer","cachingDelta","_autoplay","CACHE","skipDelta","contexts","setMainLoop","clearPendingRAF","rafId","resetCurrentFrame","minFrame","requestFrame","applyInversing","renderFrame2","cachedSource","renderedFirstFrame","ImageBitmap","frInterval","frThen","frameNew","onLap","mainLoopForwards","mainLoopBackwards","currentMethod","frameListener","listenerResults","enterFrame","playToFrame","bounds","setMinMax","playToFrameOnFrameCallback","setInverseColor","pagesManager","pageId","pagesDiv","scrollableDiv","page","onShown","setPage","isAuthPage","Page","onFirstMount","encodeEmoji","emojiText","toCodePoints","removeVS16s","vs16RegExp","zeroWidthJoiner","rawEmoji","unicodeSurrogates","points","getEmojiToneIndex","VIRTUAL_COUNTRIES_EMOJIS","getCountryEmoji","emojiFromCodePoints","fromCodePoint","module","exports","defineProperty","enumerable","Symbol","toStringTag","__esModule","prototype","isRecordingSupported","bufferLength","encoderApplication","encoderFrameSize","encoderPath","maxFramesPerPage","mediaTrackConstraints","resampleQuality","streamPages","wavBitDepth","encodedSamplePosition","WebAssembly","clearStream","audioContext","closeAudioContext","encodeBuffers","getChannelData","encoder","buffers","initAudioContext","initAudioGraph","scriptProcessorNode","createScriptProcessor","destination","onaudioprocess","inputBuffer","monitorGainNode","setMonitorGain","recordingGainNode","setRecordingGain","initSourceNode","loadWorker","initWorker","streamPage","storePage","recordedPages","samplePosition","finish","originalSampleRate","sampleRate","wavSampleRate","onpause","resume","onresume","setTargetAtTime","onstart","destroyWorker","Function","kSampleStepSize","float32ArraySupported","Float32Array","A","aA1","aA2","B","C","calcBezier","aT","getSlope","LinearEasing","mX1","mY1","mX2","mY2","sampleValues","aX","intervalStart","currentSample","kSplineTableSize","guessForT","initialSlope","aGuessT","currentSlope","newtonRaphsonIterate","aA","aB","currentX","currentT","binarySubdivide","getTForX"],"sourceRoot":""}