{"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;\n\n private overrideIdleGroups: Set;\n private byGroups: {[group in AnimationItemGroup]?: AnimationItem[]};\n private byPlayer: Map;\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) => void,\n pause: () => void,\n playbackParams: (params: ReturnType) => void,\n stop: () => void,\n}> {\n private container: HTMLElement;\n private media: Map> = new Map();\n private scheduled: AppMediaPlaybackController['media'] = new Map();\n private mediaDetails: Map = new Map();\n private playingMedia: HTMLMediaElement;\n private playingMediaType: PlaybackMediaType;\n\n private waitingMediaForLoad: Map>> = new Map();\n private waitingScheduledMediaForLoad: AppMediaPlaybackController['waitingMediaForLoad'] = new Map();\n private waitingDocumentsForLoad: {[docId: string]: Set} = {};\n\n public willBePlayedMedia: HTMLMediaElement;\n private searchContext: MediaSearchContext;\n\n private listLoader: SearchListLoader;\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 = {\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) {\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();\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;\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[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;\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 \n
\n
\n
\n
\n \n
\n \n / \n \n
\n
\n
\n \n ${!IS_MOBILE && document.pictureInPictureEnabled ? `` : ''}\n \n
\n
\n
`;\n }\n }\n\n protected setBtnMenuToggle() {\n const buttons = VideoPlayer.PLAYBACK_RATES.map((rate, idx) => {\n const buttonOptions: Parameters[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;\n\n protected isFirstOpen = true;\n\n protected pageEl = document.getElementById('page-chats') as HTMLDivElement;\n\n protected setMoverPromise: Promise;\n protected setMoverAnimationPromise: Promise;\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;\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 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,\n topButtons: Array['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 = ``;\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 = ``;\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).cleanup && (this.listLoader as SearchListLoader).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();\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;\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 = 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;\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 = 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;\n private id: number;\n private manual: boolean;\n private log: ReturnType;\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 = 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, 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[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[],\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 = Promise.resolve();\n\n private nextRates: Partial<{[type in SearchSuperType]: number}> = {};\n private loadPromises: Partial<{[type in SearchSuperType]: Promise}> = {};\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;\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 = 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;\n\n private listenerSetter: ListenerSetter;\n private swipeHandler: SwipeHandler;\n\n constructor(options: Pick) {\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;\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[] = [];\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>;\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[] = [];\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)[] = 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 = 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, '$1');\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 = (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;\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 = 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}[] = 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[] = 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', ``);\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();\n\n public freezed = false;\n\n private folderId = 0;\n private offsetIndex = 0;\n private promise: Promise;\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 = 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;\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;\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 {\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[] = [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} = {\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 = ``;\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 = ''\n speechRecognitionDiv.append(speechRecognitionIcon);\n\n speechRecognitionDiv.onclick = () => {\n const speechTextDiv = (findUpClassName(audioEl, 'document-wrapper') || findUpClassName(audioEl, 'quote-text')).querySelector('.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
\n
\n
\n
`;\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[];\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;\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
\n
\n
\n
\n
\n
`;\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();\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();\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 extends ListLoader {\n private peerId: PeerId;\n private managers: AppManagers;\n\n constructor(options: Omit, '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> = new Map();\nconst seen: Set = 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[];\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[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[],\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) => void, options?: ConstructorParameters[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(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[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,\n waitForAnimation?: boolean\n /* , cancelEvent?: true */\n};\n\nexport type ButtonMenuItemOptionsVerifiable = ButtonMenuItemOptions & {\n verify?: () => boolean | Promise\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[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[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;\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 = []; // descend sorted\n private itemsMap: Map = new Map();\n public groups: Array = []; // descend sorted\n private newGroupDiff = 121; // * 121 in scheduled messages\n private sortItemsKey: Extract;\n private sortGroupsKey: Extract;\n public sortGroupItemsKey: Extract;\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 = 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) {\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) {\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 = 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[];\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 = `${replies?.replies ? formatNumber(replies.replies, 0) : ''}`;\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 = ' ';\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[],\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>;\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[],\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;\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;\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 ? '' : '';\n const votes = poll.answers.map((answer, idx) => {\n return `\n
\n
\n
\n \n \n \n ${multipleSelect}\n
\n
\n
\n \n \n \n \n
\n `;\n }).join('');\n\n this.innerHTML = `\n
\n
\n
\n
\n
\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 = 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 = 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 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,\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;\n private getHistoryBottomPromise: Promise;\n\n // public messagesCount: number = -1;\n\n private unreadOut = new Set();\n public needUpdate: {replyToPeerId: PeerId, replyMid: number, mid: number}[] = []; // if need wrapSingleMessage\n\n public bubbles: {[mid: string]: HTMLElement} = {};\n public skippedMids: Set = 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 = new Map();\n private unreadedSeen: Set = new Set();\n private readPromise: Promise;\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;\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;\n\n private passEntities: Partial<{\n [_ in MessageEntity['_']]: boolean\n }> = {};\n\n private onAnimateLadder: () => Promise | void;\n // private ladderDeferred: CancellablePromise;\n private resolveLadderAnimation: () => Promise;\n private emptyPlaceholderBubble: HTMLElement;\n\n private viewsMids: Set = new Set();\n private sendViewCountersDebounced: () => Promise;\n\n private isTopPaddingSet = false;\n\n private getSponsoredMessagePromise: Promise;\n\n private previousStickyDate: HTMLElement;\n private sponsoredMessage: SponsoredMessage.sponsoredMessage;\n\n private hoverBubble: HTMLElement;\n private hoverReaction: HTMLElement;\n private sliceViewportDebounced: DebounceReturnType;\n private resizeObserver: ResizeObserver;\n private willScrollOnLoad: boolean;\n public observer: SuperIntersectionObserver;\n\n private renderingMessages: Set = new Set();\n private setPeerCached: boolean;\n private attachPlaceholderOnRender: () => void;\n\n private bubblesToEject: Set = new Set();\n private bubblesToReplace: Map = 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> = new Set();\n private updateGradient: boolean;\n\n private extendedMediaMessages: Set = new Set();\n private pollExtendedMediaMessagesPromise: Promise;\n\n private batchProcessor: BatchProcessor>>;\n\n private ranks: Map>;\n private processRanks: Set<() => void>;\n private canShowRanks: boolean;\n // private reactions: Map;\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('.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;\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(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('.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('.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 = 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, 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>;\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[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(); */\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;\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('.attachment');\n if(attachment) {\n if(albumItemMid) {\n attachment = attachment.querySelector(`[data-mid=\"${albumItemMid}\"]`);\n }\n\n const media = attachment.querySelector('img, video, canvas');\n this.checkTargetForMediaViewer(media, undefined, timestamp);\n return;\n }\n\n const audio = (groupedItem || bubble).querySelector('.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) {\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,\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(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) => {\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[]);\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) {\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> &\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,\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, 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> & {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[] = [];\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;\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[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;\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((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) ? '' : `
${appPeersManager.getPeerTitle(message.fromId)}
`;\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 | 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[] = [];\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[] = [];\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();\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;\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[] = [];\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[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, 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[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(service?: T, fill?: (message: GenerateLocalMessageType) => void, addOffset = 0): Promise> {\n const {id, mid} = this.generateLocalMessageId(addOffset);\n let message: Omit & {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>(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, 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, waitPromise: Promise}> {\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 = 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) => {\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) => {\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, 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;\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;\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[],\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[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 = 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;\n public scrollable: ScrollableBase;\n private animationGroup: AnimationItemGroup;\n private middleware: ReturnType;\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(player);\n\n players.appear = player;\n\n player.addEventListener('enterFrame', (frameNo) => {\n if(player.maxFrame === frameNo) {\n selectLoadPromise.then((selectPlayer) => {\n assumeType(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(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,\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;\n private canOpenReactedList: boolean;\n\n private emojiInputsPromise: CancellablePromise;\n private albumMessages: Message.message[];\n private linkToMessage: Awaited>;\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(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 = 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,\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;\n\n this.lazyLoadQueue.clear();\n if(stickers.length) {\n ready = new Promise((resolve) => {\n const promises: Promise[] = [];\n stickers.forEach((sticker) => {\n container.append(this.superStickerRenderer.renderSticker(sticker as MyDocument, undefined, promises));\n });\n\n (Promise.all(promises) as Promise).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;\n\n if(query !== undefined) {\n index = new SearchIndex({\n ignoreCase: true\n });\n }\n\n type T = {peerId: PeerId, name: string, description: string, index: number, command: string};\n const commands: Map = 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 = 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 {\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>;\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[] = [];\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(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(acked: AckedResult): Promise, {result: T | Promise}>> {\n return {\n cached: acked.cached,\n result: acked.cached ? await acked.result : acked.result\n };\n}\n\nexport function modifyAckedPromise(promise: Promise>) {\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;\n private middleware: ReturnType;\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[] = 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> {\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;\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;\n private helperFunc: () => void | Promise;\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) {\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\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 \n \n \n \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).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[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 = (!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, 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 = 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[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[0] = '',\n subtitle: Parameters[1] = '',\n input?: Parameters[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[]) {\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>['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),\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> = 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;\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[],\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,\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> {\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>) => {\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> = 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;\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 = 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[] = [];\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 => {\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[] = [];\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 {\n public fields: Array;\n protected listenerSetter: ListenerSetter;\n protected asRestrictions: boolean;\n\n constructor(options: {\n fields: Array,\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;\nexport type PopupConfirmationOptions = PopupPeerOptions & {\n button: PopupPeerOptions['buttons'][0],\n checkbox?: PopupPeerOptions['checkboxes'][0]\n};\n\nexport default function confirmationPopup(\n options: T\n): Promise : (T['checkbox'] extends PopupPeerCheckboxOptions ? boolean : void)> {\n return new Promise((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;\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 = [];\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('[data-default-name]').dataset.defaultName;\n const phoneCodeEl = target.querySelector('.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 {\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;\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[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, 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;\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 = `
`;\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 = {\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;\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,\n menu: HTMLElement,\n scrollable: Scrollable,\n menuScroll?: ScrollableX,\n prevTab?: StickersTabCategory,\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 = 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;\ntype EmojiTabCategory = StickersTabCategory;\nexport default class EmojiTab extends EmoticonsTabC {\n private closeScrollTop: number;\n private menuInnerScroll: ScrollableX;\n private isStandalone?: boolean;\n private noRegularEmoji?: boolean;\n private stickerSetId?: Parameters[0];\n private onClick: (emoji: EmojiTabItem) => void;\n private activeEmoji: ReturnType;\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) => {\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[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[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[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;\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,\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) {\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 = 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 = 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[]) {\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 = {}> {\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['getContainerSize'],\n getElementMediaSize: StickersTabCategory['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> 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;\n protected categoriesByMenuTabMap: Map;\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;\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 = (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> {\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,\n promise: Promise\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) => {\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, 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, 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, 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 = 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();\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,\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[] = [];\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('[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('.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('.input-filler')).map((el) => {\n // el.contentEditable = 'false';\n // return el;\n // });\n\n const customEmojiElements = Array.from(fragment.querySelectorAll('.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('[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('.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(//, '');\n html = html.replace(//, '');\n html = html.replace('
', '');\n\n const match = html.match(/([\\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

asd

\\n

zxc

\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

(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('.custom-emoji, .custom-emoji-placeholder'));\n let renderer = input.querySelector('.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[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 = `

`;\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 \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[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[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(`(${BOM})|()`, '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(//, '')\n .replace(/().+?\\/custom-emoji-element>/g, '$1')\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[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 & {\n load: (target?: HTMLElement) => Promise,\n div: HTMLElement\n wasSeen?: boolean,\n visible?: boolean\n};\n\nexport default class LazyLoadQueueIntersector extends LazyLoadQueueBase {\n protected queue: Array = [];\n protected inProcess: Set = 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) {\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) {\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 *
A Javascript solution to middle ellipsis
\n *
A Javascript solution to middle ellipsis
\n *
A Javascript solution to middle ellipsis
\n */\nconst ellipsis = '…';\nconst map: Map = new Map();\n\nconst testQueue: Set = 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;\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;\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;\n private peerId: PeerId;\n private intersectionObserver: IntersectionObserver;\n private loadCallbacks: Map 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, ReturnType] = [] 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[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(\n needClear = false,\n manual?: T\n ): Promise 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(manual?: T): T extends true ? Promise<() => void> : Promise {\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) {\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();\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) {\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[] = [];\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 = 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),\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) => 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) => 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;\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,\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) {\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 = 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,\n title: boolean | LangPackKey,\n titleRaw: string\n}>;\n\nexport interface PopupElementConstructable {\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 extends EventListenerBase {\n private static POPUPS: PopupElement[] = [];\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;\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('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('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(popupConstructor: PopupElementConstructable) {\n return this.POPUPS.filter((element) => element instanceof popupConstructor) as T[];\n }\n\n public static createPopup>(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 {\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,\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 = 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 | (() => 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 {\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(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(length: number, fill?: T1, map?: any): T1[] {\n const arr = new Array(length);\n arr.fill(fill);\n return map ? arr.map(map) : arr;\n}\n","const delta = '0'.charCodeAt(0) - '0'.charCodeAt(0);\nconst buggedRegExp = /[0-9]/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 = [];\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, 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[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;\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;\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 = 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[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 | 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;\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[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[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((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 & Partial<{callback: PopupPeerButtonCallback}>;\nexport type PopupPeerButtonCallbackCheckboxes = Set;\nexport type PopupPeerButtonCallback = (checkboxes?: PopupPeerButtonCallbackCheckboxes) => void;\nexport type PopupPeerCheckboxOptions = CheckboxFieldOptions & {checkboxField?: CheckboxField};\n\nexport type PopupPeerOptions = Omit & Partial<{\n peerId: PeerId,\n threadId: number,\n title: string | HTMLElement,\n titleLangKey: LangPackKey,\n titleLangArgs: any[],\n noTitle: boolean,\n description: Parameters[1],\n descriptionLangKey: LangPackKey,\n descriptionLangArgs: any[],\n buttons: Array,\n checkboxes: Array\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 = 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,\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[0] | Parameters[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[] = [];\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;\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 = 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
\n \n \n \n
`;\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 \n \n \n \n \n \n \n \n \n \n \n `;\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) {\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) {\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 {\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 {\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 {\n if(this.proportions[0] === 'w') {\n return this.layoutFourTopAndOther();\n }\n return this.layoutFourLeftAndOther();\n }\n\n private layoutTwoTopBottom(): ReturnType {\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 {\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 {\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 {\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 {\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 {\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 {\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(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;\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[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 \n \n `;\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) {\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', `
${subtitle}
`);\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 = () => 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;\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[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) {\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[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 = 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;\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) {\n this.container.append(...args);\n }\n\n public scrollIntoViewNew(options: Omit) {\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 = 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;\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;\n public radioSection: SettingSection;\n public exceptions: Map;\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) {\n this.container.classList.add('dont-u-dare-block-me');\n this.setTitle('PrivacySettings');\n\n const SUBTITLE: LangPackKey = 'Loading';\n const promises: Promise[] = [];\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 = [\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;\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) {\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[] = [];\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();\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 = 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[] = [];\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;\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 = 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[] = [];\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;\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) {\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 = new Map();\n\n const promise = Promise.all([\n p.languages1,\n p.languages2\n ]).then(([languages1, languages2]) => {\n const rendered: Set = 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) {\n this.container.classList.add('stickers-emoji-container');\n this.setTitle('StickersName');\n\n const promises: Promise[] = [];\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(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;\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 extends {\n new (...args: any[]): infer U;\n } ? U : never;\n\n const m = (\n icon: string,\n text: LangPackKey,\n c: T,\n getInitArgs?: () => Promise['init']>>\n ): {\n icon: string,\n text: LangPackKey,\n tabConstructor: T,\n getInitArgs?: typeof getInitArgs,\n // args?: ReturnType\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 = (c: T): () => [ReturnType['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;\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 = 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;\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;\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})[] = [{\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 \n \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 | 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) {\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) => void;\n\n constructor() {\n this.container = document.createElement('div');\n this.container.classList.add(ColorPicker.BASE_CLASS);\n\n const html = `\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\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 = new Set();\n private blurCheckboxField: CheckboxField;\n\n private wallPapersByElement: Map = new Map();\n private elementsByKey: Map = 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 = 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 = appDownloadManager.getNewDeferredForUpload(file.name, uploadPromise);\n\n const deferred = deferredPromise();\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[] = [];\n let wrapped: ReturnType, size: ReturnType;\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();\n let download: Promise | ReturnType;\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;\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((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>;\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;\n\n public static getInitArgs() {\n return {\n animationData: lottieLoader.loadAnimationFromURLManually('Folders_2')\n };\n }\n\n public init(p: ReturnType = 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;\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[] = 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) {\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[] = [];\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[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[] = [];\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((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 {\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 = 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): 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 = 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,\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[] = [];\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) {\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(manual?: T): Promise 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;\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; // * 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;\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(tabConstructor: SliderSuperTabConstructable) {\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(\n ctor: SliderSuperTabConstructable,\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 {\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) {\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 {\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,\n destroyAfter: (promise: Promise) => 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 {\n dom: DialogDom\n}\n\nexport default class SortedUserList extends SortedList {\n protected static SORT_INTERVAL = 30e3;\n public list: HTMLUListElement;\n public ranks: Map> = new Map();\n\n protected lazyLoadQueue: LazyLoadQueue;\n protected avatarSize: DialogElementSize = 'abitbigger';\n protected rippleEnabled = true;\n protected autonomous = true;\n protected createChatListOptions: Parameters[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[]) {\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((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((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('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>;\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>;\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 & {\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;\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;\n private initialDragOffset: {x: number, y: number};\n private isDragCanceled: {x: boolean, y: boolean};\n private wheelZoom: number;\n private releaseWheelDrag: ReturnType void>>;\n private releaseWheelZoom: ReturnType void>>;\n\n private log: ReturnType;\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) {\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();\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) => 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;\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 = 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 = new Map();\n let animationDeferred: CancellablePromise;\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;\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();\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;\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\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 {\n row: Row\n }\n\n const sortedList = new SortedList({\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;\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 = 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[]\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[0]) {\n const loadPromises: Promise[] = 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[],\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 {\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 = ``;\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 ? '' : `
`}\n
\n
\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) => {\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;\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;\n\nexport default async function getPeerTitle(\n options: T\n): Promise {\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>['image']\n} & Parameters[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[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(\n options: T\n): Promise {\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 = 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 \n \n \n \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,\n plain?: boolean\n} & WrapSomethingOptions;\nexport async function wrapTopicIcon(options: T): Promise {\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 // \n // \n // \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>;\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;\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;\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;\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;\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 & {\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;\n// export default async function wrapMessageForReply(message: MyMessage | MyDraftMessage, text?: string, usingMids?: number[], plain?: false, highlightWord?: string, withoutMediaType?: boolean): Promise;\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 {\nexport default async function wrapMessageForReply(\n options: T\n): Promise {\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);\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 | 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,\n withoutPreloader?: boolean,\n loadPromises?: Promise[],\n autoDownloadSize?: number,\n noBlur?: boolean,\n noThumb?: boolean,\n noFadeIn?: boolean,\n blurAfter?: boolean,\n managers?: AppManagers,\n processUrl?: (url: string) => Promise\n}) {\n const ret = {\n loadPromises: {\n thumb: Promise.resolve() as Promise,\n full: Promise.resolve() as Promise\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 = 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;\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[0],\n subtitle: Parameters[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} = {};\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[],\n needFadeIn?: boolean,\n needUpscale?: boolean,\n skipRatio?: number,\n static?: boolean,\n managers?: AppManagers,\n fullThumb?: PhotoSize | Extract,\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();\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();\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(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;\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;\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> | 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,\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,\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(_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[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;\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[] = 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[0], 'peerId' | 'threadId' | 'wrapOptions' | 'withIcons'>\n) {\n const {peerId, threadId, lastMsgId} = options;\n\n const loadPromise: Promise = 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[],\n autoDownload?: ChatAutoDownloadSettings,\n photoSize?: PhotoSize,\n videoSize?: Extract,\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\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 = `\n \n `;\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>;\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();\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 = 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\n}\n\ntype AnimationInstanceKey = any;\nconst instances: Map = new Map();\n\nexport function createAnimationInstance(key: AnimationInstanceKey) {\n cancelAnimationByKey(key);\n\n const instance: AnimationInstance = {\n isCancelled: false,\n deferred: deferredPromise()\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(arr: T[], callback: (item: T, idx: number, arr: T[]) => Promise | 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(array: Array, 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(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 {\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> = {\n items: ArgumentTypes[],\n process: (...args: any[]) => ReturnType,\n context: any,\n promise?: CancellablePromise[]>\n};\nconst heavyQueue: HeavyQueue[] = [];\nlet processingQueue = false;\n\nexport default function addHeavyTask>(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>(queue: HeavyQueue) {\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[] = [];\n\n return new Promise((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;\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};\nconst cache: Map = 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 \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(options: T): Promise {\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 \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({\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,\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(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 & {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 \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;\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 \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}[];\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(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(types: T[], onlyFull?: boolean) {\n const result: Record = {} 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 = {} 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 \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 += '
';\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 \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[0], url: string, useCache?: boolean) {\n return new Promise((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[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;\n\n private log: ReturnType;\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('[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) {\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,\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) => {\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('.input-something').forEach((el) => {\n // el.contentEditable = 'inherit';\n // });\n\n // addInputCallback(() => {\n // this.messageInput.querySelectorAll('.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, '\\n');\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('.input-something').forEach((el) => {\n // el.contentEditable = 'inherit';\n // });\n // addInputCallback(() => {\n // this.messageInput.querySelectorAll('.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('.input-something').forEach((el) => {\n el.contentEditable = 'inherit';\n });\n addInputCallback(() => {\n input.querySelectorAll('.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('.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('.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('.input-filler');\n // fillers.forEach((el) => {\n // el.contentEditable = 'false';\n // });\n\n const smths = input.querySelectorAll('.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 | 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;\n protected ignoreButtons: Set;\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 {\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 = 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;\nexport type FramesCacheMapNew = Map;\nexport type FramesCacheMapURLs = Map;\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;\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;\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 = {\n loadMore: ListLoader['loadMore'],\n loadCount?: ListLoader['loadCount'],\n loadWhenLeft?: ListLoader['loadWhenLeft'],\n processItem?: ListLoader['processItem'],\n onJump?: ListLoader['onJump'],\n onLoadedMore?: ListLoader['onLoadedMore']\n};\n\nexport type ListLoaderResult = {count: number, items: any[]};\nexport default class ListLoader {\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>;\n protected processItem: (item: P) => T | Promise;\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;\n protected loadPromiseDown: Promise;\n\n constructor(options: ListLoaderOptions) {\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)[] = [];\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;\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 = new Set();\n\n public add(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(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(\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 (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).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((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((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(fn: F) {\n return throttleWith(fastRaf, fn);\n}\n","// * Jolly Cobra's schedulers\n\nimport {AnyToVoidFunction} from '../../types';\n\nexport default function throttleWith(schedulerFn: AnyToVoidFunction, fn: F) {\n let waiting = false;\n let args: Parameters;\n\n return (..._args: Parameters) => {\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;\n private promise: Promise;\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 extends ListLoader {\n public searchContext: MediaSearchContext;\n public onEmptied: () => void;\n\n private otherSideLoader: SearchListLoader;\n private managers: AppManagers;\n\n constructor(options: Omit, '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}) => {\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['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,\n write: CancellablePromise\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();\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\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 = {\n id: T,\n index: number\n};\n\nlet id = 0;\n\nexport class BatchProcessor {\n protected queue: Promise[];\n protected promise: Promise;\n\n protected middlewareHelper: MiddlewareHelper;\n protected log: ReturnType;\n\n protected process: (batch: Item[], m: ReturnType, log: BatchProcessor['log']) => Promise;\n protected possibleError: any;\n\n constructor(options: {\n log?: BatchProcessor['log'],\n // middleware: MiddlewareHelper,\n process: BatchProcessor['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['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 => {\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 {\n protected elements: Map;\n protected sorted: Array;\n\n protected getIndex: (element: SortedElement) => PromiseLike | 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;\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;\n\n protected log: ReturnType;\n\n constructor(options: {\n getIndex: SortedList['getIndex'],\n onDelete?: SortedList['onDelete'],\n onUpdate?: SortedList['onUpdate'],\n onSort?: SortedList['onSort'],\n onElementCreate: SortedList['onElementCreate'],\n\n updateElementWith?: SortedList['updateElementWith'],\n updateListWith?: SortedList['updateListWith'],\n\n log?: SortedList['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({\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, '&').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, '>');\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((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 = deferredPromise();\nlet promisesInQueue = 0;\n\nheavyAnimationPromise.resolve();\n\nconst log = console.log.bind(console.log, '[HEAVY-ANIMATION]:');\n\nexport function dispatchHeavyAnimationEvent(promise: Promise, timeout?: number) {\n if(!isAnimating) {\n heavyAnimationPromise = deferredPromise();\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;\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,\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,\n mentionsBadge?: HTMLElement,\n lastMessageSpan: HTMLSpanElement,\n containerEl: HTMLElement,\n listEl: HTMLElement,\n subtitleEl: HTMLElement,\n\n setLastMessagePromise?: CancellablePromise,\n setUnreadMessagePromise?: CancellablePromise\n};\n\ninterface SortedDialog extends SortedElementBase {\n dom: DialogDom,\n dialogElement: DialogElement\n}\n\nfunction setPromiseMiddleware}, K extends keyof T>(obj: T, key: K) {\n const oldPromise: CancellablePromise = obj[key] as any;\n oldPromise?.reject();\n\n // @ts-ignore\n const deferred = obj[key] = deferredPromise();\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 {\n public managers: AppManagers;\n public log: ReturnType;\n public list: HTMLElement;\n public indexKey: ReturnType;\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[] = [];\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[],\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,\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;\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[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[0];\nclass Some {\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;\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;\n protected placeholder: DialogsPlaceholder;\n protected log: ReturnType;\n protected placeholderOptions: ConstructorParameters[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();\n const renderPromise = new Promise(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[0]['getRectFrom'] {\n throw NOT_IMPLEMENTED_ERROR;\n }\n\n public getDialogFromElement(element: HTMLElement): Promise {\n throw NOT_IMPLEMENTED_ERROR;\n }\n\n public loadDialogsInner(side: SliceSides): ReturnType {\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 {\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 {\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[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;\n\n private lastActiveElements: Set = new Set();\n\n public loadContacts: () => void;\n public processContact: (peerId: PeerId) => void;\n\n private initedListeners = false;\n\n public onListLengthChange: () => Promise;\n private allChatsIntlElement: I18n.IntlElement;\n\n private emptyDialogsPlaceholderSubtitle: I18n.IntlElement;\n private updateContactsLengthPromise: Promise;\n\n private filtersNavigationItem: NavigationItem;\n\n private managers: AppManagers;\n private selectTab: ReturnType;\n\n public doNotRenderChatList: boolean;\n\n private stateMiddlewareHelper: MiddlewareHelper;\n\n private forumsTabs: Map;\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[] = [];\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 = isLoadedMain ? Promise.resolve() : this.managers.appMessagesManager.getConversationsAll('', 0);\n const b: Promise = 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[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;\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[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) {\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, 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();\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[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 | HTMLElement)[] = [];\n if(lastMessage && !draftMessage && !isRestricted) {\n const media = getMediaFromMessage(lastMessage, true);\n const videoTypes: Set = 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[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\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[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[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[] = [];\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[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, controller: AbortController};\nexport type DownloadJson = {promise: Promise, controller: AbortController}; */\nexport type DownloadBlob = CancellablePromise;\nexport type DownloadUrl = CancellablePromise;\nexport type DownloadJson = CancellablePromise;\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} = {};\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(fileName: string, type?: DownloadType) {\n const deferred = deferredPromise();\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)[]).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>(fileName: string, promise: T) {\n const deferred = this.getNewDeferred(fileName);\n promise.then(deferred.resolve, deferred.reject);\n\n deferred.finally(() => {\n this.clearDownload(fileName);\n });\n\n return deferred as CancellablePromise>;\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['promise'] {\n let deferred: CancellablePromise = 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(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, type?: DownloadType) {\n let deferred = this.getDownload(fileName, type);\n if(deferred) return deferred;\n\n deferred = this.getNewDeferred(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): 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) {\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;\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;\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) => {\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) => {\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 = 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;\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 = 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[] = [];\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};\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[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;\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[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;\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).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;\n // private createCanvasPatternPromise: Promise;\n // private exportCanvasPatternToImagePromise: Promise;\n private renderImageFromUrlPromise: Promise;\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((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[] = [];\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;\n public peerChanged: boolean;\n\n public log: ReturnType;\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;\n public sharedMediaTab: AppSharedMediaTab;\n public sharedMediaTabs: AppSharedMediaTab[];\n // public renderDarkPattern: () => Promise;\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 {\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((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;\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) {\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;\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(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 {\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;\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 = 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;\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;\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;\n public loadPromises: Map>;\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) {\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[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[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 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;\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 {\n dom: DialogDom,\n mutedIcon: GroupCallParticipantMutedIcon,\n status: GroupCallParticipantStatusElement\n}\n\nexport default class GroupCallParticipantsList extends SortedList {\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[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>;\n private displayPinned: boolean;\n private containers: Map;\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})[];\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[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('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;\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;\n\n private avatarCanvas: HTMLCanvasElement;\n private avatarContext: CanvasRenderingContext2D;\n private avatarGradients: {[color: string]: CanvasGradient};\n\n private log: ReturnType;\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();\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[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 \n \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 {\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((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[] = [];\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(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;\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;\n\n public setPeerPromise: Promise = 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};\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\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(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(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(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);\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);\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 => {\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(type: T, uriParams: Omit) {\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) {\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[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) {\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 {\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 {\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('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('.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 = 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 = {}, animate?: boolean): Promise {\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[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;\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> {\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 = {\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>;\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\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;\n protected log: ReturnType;\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 = 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;\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[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,\n}> {\n public dh: Partial;\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;\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;\n\n private decryptQueue: Uint8Array[];\n\n private getEmojisFingerprintPromise: Promise;\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 {\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[] = 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,\n video: Promise\n }>,\n screen: Partial<{\n audio: Promise,\n video: Promise\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 = 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 extends EventListenerBase {\n protected log: ReturnType;\n protected outputDeviceId: string;\n\n protected player: HTMLElement;\n protected elements: Map;\n\n protected audio: HTMLAudioElement;\n // protected fixedSafariAudio: boolean;\n\n protected getStream: ReturnType;\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;\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;\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;\n private managers: AppManagers;\n private audioAsset: AudioAssetPlayer;\n private instances: Map;\n private sortedInstances: Array;\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,\n isMuted?: boolean,\n joinVideo?: boolean,\n rejoin?: boolean\n } | {\n type: Extract,\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 = 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;\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;\n private participantsSsrcs: Map;\n private hadAutoPinnedSources: Set;\n private dispatchPinnedThrottled: () => void;\n private startVideoSharingPromise: Promise;\n private startScreenSharingPromise: Promise;\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) {\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 = 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;\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;\n private log: ReturnType;\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;\n private entriesBySource: Map;\n private entriesByPeerId: Map>;\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[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[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[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;\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;\n #prefix: string;\n #nestedMap: Map;\n #missed: boolean;\n #keys: Array;\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['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> = 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>) {\n const out: Map = 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;\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> = 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;\n #mediaLine: SDPLine;\n #attributes: SDPAttributes;\n #direction: SDPMediaDirection;\n\n constructor(lines: Array) {\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(keys: NoExtraProperties): {[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[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;\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[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;\n\nexport class CustomEmojiRendererElement extends HTMLElement {\n public canvas: HTMLCanvasElement;\n public context: CanvasRenderingContext2D;\n\n public playersSynced: Map;\n public clearedElements: WeakSet;\n public customEmojis: Parameters[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 = 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) {\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[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[] = [];\n const wrap = (doc: MyDocument, _loadPromises?: Promise[]) => {\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[] = [];\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['render']>) => Promise,\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(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,\n pausedElements: Set,\n key: string\n};\ntype CustomEmojiFrame = Parameters[0] | HTMLVideoElement;\n\nconst CUSTOM_EMOJI_INSTANT_PLAY = true; // do not wait for animationIntersector\nlet emojiRenderInterval: number;\nconst emojiRenderers: Set = new Set();\nconst syncedPlayers: Map = new Map();\nconst syncedPlayersFrames: Map = 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[],\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,\n customWraps?: Set,\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;\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, '', '');\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, '', '');\n } */\n /* if(!isSupported) {\n insertPart(entity, `\"`,`);\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, '
');\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, ``, '');\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) {\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 = !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} = {};\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, name: LottieAssetName) {\n // (params as RLottieOptions).name = name;\n return this.loadAnimationFromURL(params, this.makeAssetUrl(name));\n }\n\n public loadAnimationDataFromURL(url: string): Promise {\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((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) => this.loadAnimationFromURLNext(blob, params, url);\n });\n }\n\n public loadAnimationFromURL(params: Omit, 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, 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((resolve) => {\n player.addEventListener('firstFrame', () => {\n setTimeout(() => resolve(), 1500);\n }, true);\n }) */\n new Promise((resolve) => {\n player.addEventListener('firstFrame', resolve, {once: true});\n }),\n pause(2500)\n ]).then(() => player);\n }\n\n public async loadAnimationWorker(params: RLottieOptions): Promise {\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[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;\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 | void,\n private onMount?: (...args: any[]) => Promise | 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 {\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 = 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{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":""}