{"version":3,"file":"684.c02f8f5d69deae872060.chunk.js","mappings":"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AAO,KAAO,MAAO,KAAO,MAAO,KAAO,MAAO,KAAO,MAAO,YAAY,MAAO,YAAY,MAAO,YAAY,MAAO,YAAY,MAAO,YAAY,MAAO,YAAY,MAAO,YAAY,MAAO,YAAY,MAAO,YAAY,MAAO,YAAY,MAAO,YAAY,MAAO,YAAY,MAAO,OAAO,MAAO,OAAO,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,QAAQ,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,cAAc,MAAO,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,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,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,uBAAuB,EAAG,uBAAuB,EAAG,uBAAuB,EAAG,uBAAuB,EAAG,uBAAuB,EAAG,uBAAuB,EAAG,uBAAuB,EAAG,uBAAuB,EAAG,uBAAuB,EAAG,uBAAuB,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aAAa,EAAG,aA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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/gradientRenderer.ts","webpack://tweb/./src/helpers/easing/easeOutQuad.ts","webpack://tweb/./src/components/chat/selection.ts","webpack://tweb/./src/helpers/dom/getSelectedText.ts","webpack://tweb/./src/components/checkboxField.ts","webpack://tweb/./src/components/codeInputField.ts","webpack://tweb/./src/components/confirmationPopup.ts","webpack://tweb/./src/components/countryInputField.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/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/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/limit.ts","webpack://tweb/./src/components/popups/mute.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/preloader.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/quickReaction.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/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/stickerViewer.ts","webpack://tweb/./src/components/stickyIntersector.ts","webpack://tweb/./src/components/swipeHandler.ts","webpack://tweb/./src/components/telInputField.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/peerTitle.ts","webpack://tweb/./src/components/wrappers/photo.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/filterAsync.ts","webpack://tweb/./src/helpers/array/findAndSpliceAll.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/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/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/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/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/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/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/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/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/helpers/dom/shake.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/helpers/array/partition.ts","webpack://tweb/./src/components/chat/bubbleGroups.ts","webpack://tweb/./src/components/popups/datePicker.ts","webpack://tweb/./src/components/divAndCaption.ts","webpack://tweb/./src/components/chat/replyContainer.ts","webpack://tweb/./src/components/wrappers/reply.ts","webpack://tweb/./src/components/stackedAvatars.ts","webpack://tweb/./src/components/chat/replies.ts","webpack://tweb/./src/components/chat/messageRender.ts","webpack://tweb/./src/helpers/dom/reflowScrollableElement.ts","webpack://tweb/./src/lib/mtproto/constants.ts","webpack://tweb/./src/lib/appManagers/internalLink.ts","webpack://tweb/./src/components/popups/joinChatInvite.ts","webpack://tweb/./src/components/chat/reaction.ts","webpack://tweb/./src/components/chat/reactions.ts","webpack://tweb/./src/helpers/scrollSaver.ts","webpack://tweb/./src/helpers/dom/superIntersectionObserver.ts","webpack://tweb/./src/lib/appManagers/utils/messages/isMentionUnread.ts","webpack://tweb/./src/helpers/array/accumulate.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/helpers/string/nbsp.ts","webpack://tweb/./src/components/telegramWebView.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/groupedLayout.ts","webpack://tweb/./src/components/prepareAlbum.ts","webpack://tweb/./src/components/wrappers/album.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/groupedDocuments.ts","webpack://tweb/./src/components/wrappers/poll.ts","webpack://tweb/./src/components/popups/unpinMessage.ts","webpack://tweb/./src/helpers/dom/isSelectionEmpty.ts","webpack://tweb/./src/helpers/preloadAnimatedEmojiSticker.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/sendContextMenu.ts","webpack://tweb/./src/components/popups/createPoll.ts","webpack://tweb/./src/helpers/createPoster.ts","webpack://tweb/./src/helpers/getGifDuration.ts","webpack://tweb/./src/components/inputFieldAnimated.ts","webpack://tweb/./src/components/popups/newMedia.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/helpers/dom/hasMarkupInSelection.ts","webpack://tweb/./src/components/chat/input.ts","webpack://tweb/./src/components/wrappers/draft.ts","webpack://tweb/./src/components/chat/pinnedContainer.ts","webpack://tweb/./src/components/chat/pinnedMessageBorder.ts","webpack://tweb/./src/components/chat/audio.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/lib/appManagers/appImManager.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/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 {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 controlled?: boolean | Middleware\n};\n\nexport interface AnimationItemWrapper {\n remove: () => void;\n paused: boolean;\n pause: () => any;\n play: () => any;\n autoplay: boolean;\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(\n animation: AnimationItem['animation'],\n group: AnimationItemGroup = '',\n observeElement?: HTMLElement,\n controlled?: AnimationItem['controlled']\n ) {\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 };\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\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) 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) 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) 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.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) => {\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');\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 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) 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';\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: MyPhoto | MyDocument = getMediaFromMessage(item);\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 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(await this.getMessageByPeer(target.peerId, target.mid), target.element, -1);\n };\n\n onNextClick = async(target: AppMediaViewerTargetType) => {\n this.openMedia(await this.getMessageByPeer(target.peerId, target.mid), target.element, 1);\n };\n\n onDeleteClick = () => {\n const target = this.target;\n new 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 new 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);\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 html = wrapRichText(caption, {\n entities: (message as Message.message).totalEntities\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(message: MyMessage, target?: HTMLElement, fromRight = 0, reverse = false,\n prevTargets: AppMediaViewerTargetType[] = [], nextTargets: AppMediaViewerTargetType[] = []/* , needLoadMore = true */) {\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);\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(media, message.date, fromId, fromRight, target, reverse, prevTargets, nextTargets, message/* , needLoadMore */);\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({video, play = false, streamable = false, duration, onPlaybackRackMenuToggle, onPip, onPipClose}: {\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 media: video,\n streamable,\n onSeekStart: () => {\n this.wrapper.classList.add('is-seeking');\n },\n onSeekEnd: () => {\n this.wrapper.classList.remove('is-seeking');\n }\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() {\n const 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: Parameters[0]['buttons'] = VideoPlayer.PLAYBACK_RATES.map((rate, idx) => {\n return {\n // icon: VideoPlayer.PLAYBACK_RATES_ICONS[idx],\n regularText: rate + 'x',\n onClick: () => {\n appMediaPlaybackController.playbackRate = rate;\n }\n };\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 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} 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';\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\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: this.setZoomValue,\n onMouseUp: () => this.setZoomValue()\n });\n\n this.zoomElements.container.append(this.zoomElements.btnOut, this.zoomElements.rangeSelector.container, this.zoomElements.btnIn);\n\n if(!IS_TOUCH_SUPPORTED && false) {\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,\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(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 = () => {\n this.lastDragOffset = this.lastDragDelta = {x: 0, y: 0};\n this.lastTransform = {...this.transform};\n this.moversContainer.classList.add('no-transition');\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 = () => {\n // move\n this.moversContainer.classList.remove('no-transition');\n this.clampZoomDebounced.clearTimeout();\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 ? 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 onClick = (e: MouseEvent) => {\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 const isZooming = this.isZooming;\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.innerHTML = '';\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 = rootScope.settings.animationsEnabled ? (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.innerHTML = '';\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: MyDocument | MyPhoto,\n timestamp: number,\n fromId: PeerId | string,\n fromRight: number,\n target?: HTMLElement,\n reverse = false,\n prevTargets: TargetType[] = [],\n nextTargets: TargetType[] = [],\n message?: MyMessage\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.innerHTML = '';\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(!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?.sort((a, b) => b.size - a.size);\n const cancellableFullPromise = !isDocument && appDownloadManager.downloadMediaURL({media, thumb: photoSizes?.[0]});\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 // /////this.log('indochina', blob);\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 // this.log('will renderImageFromUrl:', image, div, target);\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?.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.innerHTML = '';\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, 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';\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';\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\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\n await Promise.all(this.buttons.map(async(button) => {\n let good: boolean;\n\n if(this.isSelected && !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: async() => this.managers.appMessagesManager.canForward(await this.managers.appMessagesManager.getMessageByPeer(this.peerId, this.mid))\n }, {\n icon: 'forward',\n text: 'Message.Context.Selection.Forward',\n onClick: this.onForwardClick,\n verify: () => this.isSelected &&\n !this.searchSuper.selection.selectionForwardBtn.classList.contains('hide'),\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 }, {\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: async() => this.managers.appMessagesManager.canDeleteMessage(await this.managers.appMessagesManager.getMessageByPeer(this.peerId, this.mid))\n }, {\n icon: 'delete danger',\n text: 'Message.Context.Selection.Delete',\n onClick: this.onDeleteClick,\n verify: () => this.isSelected && !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 new 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 new 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(message, targets[idx].element, 0, false, targets.slice(0, idx), targets.slice(idx + 1));\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);\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) 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 id = this.searchContext.peerId.toChatId();\n const middleware = this.middleware.get();\n let promise: Promise;\n\n const renderParticipants = async(participants: (ChatParticipant | ChannelParticipant)[]) => {\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 = 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 for(const participant of participants) {\n const peerId = getParticipantPeerId(participant);\n if(peerId.isAnyChat()) {\n continue;\n }\n\n const user = await this.managers.appUsersManager.getUser(peerId);\n if(!middleware()) {\n return;\n }\n\n if(user.pFlags.deleted) {\n continue;\n }\n\n membersList.add(peerId);\n }\n };\n\n if(await this.managers.appChatsManager.isChannel(id)) {\n const LOAD_COUNT = !this.membersList ? 50 : 200;\n promise = this.managers.appProfileManager.getChannelParticipants(id, 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(id).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') {\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] = await Promise.all([\n this.managers.appMessagesManager.getSearchCounters(peerId, filters, undefined, threadId),\n this.canViewMembers()\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 membersTab.menuTab.classList.toggle('hide', !canViewMembers);\n\n if(canViewMembers) {\n firstMediaTab = membersTab;\n ++count;\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 }\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) 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 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 {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';\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 chatRightsAction: 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 chatRightsAction?: AppSelectPeers['chatRightsAction'],\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.chatRightsAction) {\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.chatRightsAction !== 'send_messages' || canSendToUser(peer as User.user);\n } else if(hasRights(peer as Chat.chat, this.chatRightsAction)) {\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.chatRightsAction) {\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.getChannelParticipants(\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 participants = await promise;\n if(!middleware()) {\n return;\n }\n\n const peerIds = participants.participants.map((participant) => {\n return getParticipantPeerId(participant);\n });\n indexOfAndSplice(peerIds, rootScope.myId);\n this.renderResultsFunc(peerIds);\n\n if(this.list.childElementCount >= participants.count || participants.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(rootScope.settings.animationsEnabled) {\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';\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 /* var byteIndex = (valueCount - 1) / 8 | 0;\n var bitShift = (valueCount - 1) % 8;\n if(byteIndex === waveform.length - 1) {\n var value = waveform[byteIndex];\n } else {\n var value = dataView.getUint16(byteIndex, true);\n }\n console.log('decoded waveform, setting last value:', value, byteIndex, bitShift);\n result[valueCount - 1] = (value >> bitShift) & 0b00011111; */\n return result;\n}\n\nfunction createWaveformBars(waveform: Uint8Array, duration: number) {\n const barWidth = 2;\n const barMargin = 2; // mediaSizes.isMobile ? 2 : 1;\n const barHeightMin = 4; // mediaSizes.isMobile ? 3 : 2;\n const barHeightMax = mediaSizes.isMobile ? 16 : 23;\n // const availW = 150; //mediaSizes.isMobile ? 152 : 190;\n\n const minW = mediaSizes.isMobile ? 152 : 190;\n const maxW = mediaSizes.isMobile ? 190 : 256;\n const availW = clamp(duration / 60 * maxW, minW, maxW); // mediaSizes.isMobile ? 152 : 224;\n\n const 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\n // console.log('decoded waveform:', waveform);\n\n const normValue = Math.max(...waveform);\n const wfSize = waveform.length ? waveform.length : 100;\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 \n `;\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 const container = document.createElement('div');\n container.classList.add('audio-waveform');\n container.append(svg);\n\n svg.insertAdjacentHTML('beforeend', html);\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 const fakeSvgContainer = svgContainer.cloneNode(true) as HTMLElement;\n fakeSvgContainer.classList.add('audio-waveform-fake');\n svgContainer.classList.add('audio-waveform-background');\n\n const waveformContainer = document.createElement('div');\n waveformContainer.classList.add('audio-waveform-container');\n waveformContainer.append(svgContainer, fakeSvgContainer);\n\n const timeDiv = document.createElement('div');\n timeDiv.classList.add('audio-time');\n audioEl.append(waveformContainer, timeDiv);\n\n let progress = svg as any as HTMLElement;\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 fakeSvgContainer.style.width = (audio.currentTime / audio.duration * 100) + '%';\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 audioEl.readyPromise.then(() => {\n let mousedown = false, mousemove = false;\n progress.addEventListener('mouseleave', (e) => {\n if(mousedown) {\n audio.play();\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 audio.pause();\n }\n\n scrub(e);\n mousedown = true;\n });\n progress.addEventListener('mouseup', (e) => {\n if(mousemove && mousedown) {\n audio.play();\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 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 media: audioEl.audio,\n streamable: doc.supportsStreaming\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\n private listenerSetter = new ListenerSetter();\n private onTypeDisconnect: () => void;\n public onLoad: (autoload?: boolean) => void;\n public readyPromise: CancellablePromise;\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 durationStr = toHHMMSS(doc.duration | 0);\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.innerHTML = durationStr;\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 ? (' / ' + durationStr) : '');\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 const togglePlay = (e?: Event, paused = audio.paused) => {\n e && cancelEvent(e);\n\n if(paused) {\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 audio.play().catch(() => {});\n } else {\n audio.pause();\n }\n };\n\n attachClickEvent(toggle, (e) => togglePlay(e), {listenerSetter: this.listenerSetter});\n\n this.addAudioListener('ended', () => {\n toggle.classList.remove('playing');\n audioTimeDiv.innerText = durationStr;\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 return togglePlay;\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 = (shouldPlay: boolean) => {\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 const onDownloadInit = () => {\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 onDownloadInit();\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 onDownloadInit();\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 this.listenerSetter.remove(pauseListener);\n });\n } else {\n preloader = constructDownloadPreloader();\n\n if(!shouldPlay) {\n this.readyPromise = deferredPromise();\n }\n\n const load = () => {\n onDownloadInit();\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(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 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(target.photoId, target.element, -1);\n };\n\n onNextClick = (target: AppMediaViewerAvatarTargetType) => {\n this.openMedia(target.photoId, target.element, 1);\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(photoId: Photo.photo['id'], target?: HTMLElement, fromRight = 0, prevTargets?: AppMediaViewerAvatarTargetType[], nextTargets?: AppMediaViewerAvatarTargetType[]) {\n if(this.setMoverPromise) return this.setMoverPromise;\n\n const photo = await this.managers.appPhotosManager.getPhoto(photoId);\n const ret = super._openMedia(photo, photo.date, this.peerId, fromRight, target, false, prevTargets, nextTargets);\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(message, getTarget(), undefined, undefined, prevTargets ? f(prevTargets) : undefined, nextTargets ? f(nextTargets) : undefined);\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 photo.id,\n getTarget(),\n undefined,\n prevTargets ? f(prevTargets) : undefined,\n 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 {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 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));\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 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} 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')) 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, 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 public 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 {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';\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: MessagesStorageKey = `${peerId}_${this.isScheduled ? 'scheduled' : 'history'}`;\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 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 new 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 new 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 new 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 new 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 new 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 left.style.transform = '';\n right.style.transform = '';\n }\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 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';\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 disabled?: boolean,\n checked?: boolean,\n restriction?: boolean,\n withRipple?: boolean,\n withHover?: boolean,\n listenerSetter?: ListenerSetter\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) {\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 = 'checkbox';\n if(options.name) {\n input.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\n rootScope.managers.appStateManager.setByKey(options.stateKey, value);\n };\n\n 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\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 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\n const event = new Event('change', {bubbles: true, cancelable: true});\n this.input.dispatchEvent(event);\n }\n\n public setValueSilently(checked: boolean) {\n this.input.checked = checked;\n }\n\n public toggleDisability(disable: boolean) {\n this.label.classList.toggle('checkbox-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 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 {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 new 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 {IS_MOBILE} from '../environment/userAgent';\nimport {animate} from '../helpers/animation';\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 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(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(dotRenderer, animationGroup, dotRenderer.canvas, middleware);\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.innerHTML = '';\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.innerHTML = '';\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';\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 new 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.innerHTML = '';\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';\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 constructor() {\n super({\n element: document.getElementById('emoji-dropdown') as HTMLDivElement,\n ignoreOutClickClassName: 'input-message-input'\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 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 const children = this.tabsEl.children;\n const tabsElements = Array.from(children) as HTMLElement[];\n\n const [canSendStickers, canSendGifs] = await Promise.all([\n this.managers.appMessagesManager.canSendToPeer(peerId, threadId, 'send_stickers'),\n this.managers.appMessagesManager.canSendToPeer(peerId, threadId, 'send_gifs')\n ]);\n\n tabsElements[this.stickersTab.tabId + 1].toggleAttribute('disabled', !canSendStickers);\n tabsElements[this.gifsTab.tabId + 1].toggleAttribute('disabled', !canSendGifs);\n\n const active = this.tabsEl.querySelector('.active');\n if(active && whichChild(active) !== (this.emojiTab.tabId + 1) && (!canSendStickers || !canSendGifs)) {\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';\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.innerHTML = '';\n spanEmoji.append(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(rootScope.settings.animationsEnabled) {\n image.style.opacity = '0';\n placeholder.style.opacity = '1';\n }\n\n image.addEventListener('load', () => {\n fastRaf(() => {\n if(rootScope.settings.animationsEnabled) {\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 new 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';\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 new 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_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';\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(!rootScope.settings.animationsEnabled) {\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');\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\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","/*\n * 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 media?: HTMLAudioElement | HTMLVideoElement,\n streamable?: boolean,\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 if(options.media) {\n this.setMedia(options.media, options.streamable);\n }\n }\n\n public setMedia(media: HTMLMediaElement, streamable = false) {\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();\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.max = this.media.duration;\n this.seek.setAttribute('max', '' + this.max);\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.media.duration ? end / this.media.duration : 0;\n this.filledLoad.style.width = (percents * 100) + '%';\n // this.filledLoad.style.transform = 'scaleX(' + percents + ')';\n }\n\n protected setSeekMax() {\n this.max = this.media.duration || 0;\n if(this.max > 0) {\n this.onLoadedData();\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 // fastRaf(() => {\n setInnerHTML(row.title, text || '');\n row.container.style.display = text ? '' : 'none';\n // });\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 await 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 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 new 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 = new 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 appImManager from '../../lib/appManagers/appImManager';\nimport rootScope from '../../lib/rootScope';\nimport {toastNew} from '../toast';\nimport PopupPickUser from './pickUser';\n\nexport default class PopupForward extends PopupPickUser {\n constructor(\n peerIdMids?: {[fromPeerId: PeerId]: number[]},\n onSelect?: (peerId: PeerId) => Promise | void\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 chatRightsAction: 'send_messages',\n selfPresence: 'ChatYourSelf'\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 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 {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(rootScope.settings.animationsEnabled) {\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 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: string | DocumentFragment,\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 chatRightsAction?: AppSelectPeers['chatRightsAction'],\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 chatRightsAction: options.chatRightsAction,\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';\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 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 {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","/*\n * 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';\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 = rootScope.settings.animationsEnabled;\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.innerHTML = '';\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 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\n const event = new Event('change', {bubbles: true, cancelable: true});\n this.input.dispatchEvent(event);\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';\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) => 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 );\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(!rootScope.settings.animationsEnabled) {\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(!rootScope.settings.animationsEnabled) {\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 title: 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 _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 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) {\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 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 disableWithPromise(promise: Promise) {\n this.container.classList.add('is-disabled');\n promise.finally(() => {\n this.container.classList.remove('is-disabled');\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 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 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 return Promise.all(this.peerIds.map(async(userId) => {\n const {dom} = appDialogsManager.addDialogNew({\n peerId: userId,\n container: this.list,\n rippleEnabled: false,\n avatarSize: 'abitbigger'\n });\n\n dom.lastMessageSpan.append(getUserStatusString(await this.managers.appUsersManager.getUser(userId)));\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.innerHTML = '';\n exception.row.subtitle.append(...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.innerHTML = '';\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.innerHTML = '';\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';\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 = new 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 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 = new 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';\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 new 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 new 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';\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 new 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.innerHTML = formatUserPhone(user.phone);\n else dom.lastMessageSpan.append(username ? '@' + username : getUserStatusString(user));\n }\n\n // dom.titleSpan.innerHTML = 'Raaid El Syed';\n // dom.lastMessageSpan.innerHTML = '+1 234 567891';\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';\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 row.subtitle.innerHTML = '';\n const s = i18n(langKey);\n row.subtitle.append(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 = new 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 {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 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, {CreateRowFromCheckboxField} from '../../row';\nimport AppBackgroundTab from './background';\nimport {LangPackKey, _i18n} from '../../../lib/langPack';\nimport {attachClickEvent} from '../../../helpers/dom/clickEvent';\nimport assumeType from '../../../helpers/assumeType';\nimport {BaseTheme, MessagesAllStickers, StickerSet} from '../../../layer';\nimport LazyLoadQueue from '../../lazyLoadQueue';\nimport PopupStickers from '../../popups/stickers';\nimport eachMinute from '../../../helpers/eachMinute';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport IS_GEOLOCATION_SUPPORTED from '../../../environment/geolocationSupport';\nimport AppQuickReactionTab from './quickReaction';\nimport wrapEmojiText from '../../../lib/richTextProcessor/wrapEmojiText';\nimport {DEFAULT_THEME, State} from '../../../config/state';\nimport wrapStickerSetThumb from '../../wrappers/stickerSetThumb';\nimport wrapStickerToRow from '../../wrappers/stickerToRow';\nimport SettingSection, {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';\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 allStickers: rootScope.managers.appStickersManager.getAllStickers(),\n quickReaction: rootScope.managers.appReactionsManager.getQuickReaction()\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 animationsCheckboxField = new CheckboxField({\n text: 'EnableAnimations',\n name: 'animations',\n stateKey: 'settings.animationsEnabled',\n listenerSetter: this.listenerSetter\n });\n\n container.append(\n range.container,\n chatBackgroundButton,\n CreateRowFromCheckboxField(animationsCheckboxField).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 && rootScope.settings.animationsEnabled) {\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 {\n const container = section('Emoji');\n\n const suggestCheckboxField = new CheckboxField({\n text: 'GeneralSettings.EmojiPrediction',\n name: 'suggest-emoji',\n stateKey: 'settings.emoji.suggest',\n listenerSetter: this.listenerSetter\n });\n const bigCheckboxField = new CheckboxField({\n text: 'GeneralSettings.BigEmoji',\n name: 'emoji-big',\n stateKey: 'settings.emoji.big',\n listenerSetter: this.listenerSetter\n });\n\n container.append(\n CreateRowFromCheckboxField(suggestCheckboxField).container,\n CreateRowFromCheckboxField(bigCheckboxField).container\n );\n }\n\n {\n const section = new SettingSection({name: 'Telegram.InstalledStickerPacksController', caption: 'StickersBotInfo'});\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', renderQuickReaction);\n\n const suggestCheckboxField = new CheckboxField({\n text: 'Stickers.SuggestStickers',\n name: 'suggest',\n stateKey: 'settings.stickers.suggest',\n listenerSetter: this.listenerSetter\n });\n const loopCheckboxField = new CheckboxField({\n text: 'InstalledStickers.LoopAnimated',\n name: 'loop',\n stateKey: 'settings.stickers.loop',\n listenerSetter: this.listenerSetter\n });\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 new PopupStickers({id: stickerSet.id, access_hash: stickerSet.access_hash}).show();\n },\n listenerSetter: this.listenerSetter\n });\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 section.content.append(\n reactionsRow.container,\n CreateRowFromCheckboxField(suggestCheckboxField).container,\n CreateRowFromCheckboxField(loopCheckboxField).container\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 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 apiManagerProxy from '../../../lib/mtproto/mtprotoworker';\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 async init() {\n this.setTitle('DataSettings');\n\n {\n const section = new SettingSection({name: 'AutomaticMediaDownload', caption: 'AutoDownloadAudioInfo'});\n\n const state = await apiManagerProxy.getState();\n\n const autoCheckboxField = new CheckboxField({\n text: 'AutoDownloadMedia',\n name: 'auto',\n checked: !state.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(state.settings.autoDownload, STATE_INIT.settings.autoDownload) &&\n deepEqual(state.settings.autoDownloadNew, STATE_INIT.settings.autoDownloadNew));\n };\n\n const setSubtitles = () => {\n this.setAutoDownloadSubtitle(photoRow, state.settings.autoDownload.photo /* state.settings.autoDownloadNew.photo_size_max */);\n this.setAutoDownloadSubtitle(videoRow, state.settings.autoDownload.video/* , state.settings.autoDownloadNew.video_size_max */);\n this.setAutoDownloadSubtitle(fileRow, state.settings.autoDownload.file, state.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 state.settings = settings;\n this.managers.appStateManager.setByKey('settings', settings);\n\n setSubtitles();\n autoCheckboxField.checked = !state.settings.autoDownloadNew.pFlags.disabled;\n });\n });\n\n const onDisabledChange = () => {\n const disabled = !autoCheckboxField.checked;\n\n const settings = rootScope.settings;\n if(disabled) {\n settings.autoDownloadNew.pFlags.disabled = true;\n } else {\n delete settings.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', settings);\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 const section = new SettingSection({name: 'AutoplayMedia'});\n\n section.content.append(new Row({\n checkboxField: new CheckboxField({\n text: 'AutoplayGIF',\n name: 'gifs',\n stateKey: 'settings.autoPlay.gifs',\n listenerSetter: this.listenerSetter\n }),\n listenerSetter: this.listenerSetter\n }).container, new Row({\n checkboxField: new CheckboxField({\n text: 'AutoplayVideo',\n name: 'videos',\n stateKey: 'settings.autoPlay.videos',\n listenerSetter: this.listenerSetter\n }),\n listenerSetter: this.listenerSetter\n }).container);\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 {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';\n// import AppMediaViewer from \"../../appMediaViewerNew\";\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 new 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 = Button('btn-circle btn-corner z-depth-1 profile-change-avatar', {icon: 'cameraadd'});\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 ];\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';\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: false,\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.animationsEnabled'\n })\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.innerHTML = '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.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 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.innerHTML = '';\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) {\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.innerHTML = '';\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';\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 new 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 {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: peerId\n }).element);\n // profileNameDiv.innerHTML = 'Karen Stanford';\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 new 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';\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 new 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.innerHTML = 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} from '../../../layer';\nimport appDialogsManager from '../../../lib/appManagers/appDialogsManager';\nimport Button from '../../button';\nimport SettingSection from '../../settingSection';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport getUserStatusString from '../../wrappers/getUserStatusString';\nimport {ChatPermissions} from './groupPermissions';\n\nexport default class AppUserPermissionsTab extends SliderSuperTabEventable {\n public participant: ChannelParticipant;\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 {\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 // appChatsManager.editChatDefaultBannedRights(this.chatId, p.takeOut());\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(this.chatId, this.participant).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, () => {\n const toggle = toggleDisability([btnDelete], true);\n this.managers.appChatsManager.kickFromChannel(this.chatId, this.participant).then(() => {\n this.eventListener.removeEventListener('destroy', destroyListener);\n this.close();\n });\n /* new PopupPeer('popup-group-kick-user', {\n peerId: -this.chatId,\n title: 'Ban User?',\n description: `Are you sure you want to ban ${appPeersManager.getPeerTitle(this.userId)}`,\n buttons: addCancelButton([{\n text: 'BAN',\n callback: () => {\n const toggle = toggleDisability([btnDelete], true);\n\n appChatsManager.kickFromChannel(this.chatId, this.participant).then(() => {\n this.eventListener.removeEventListener('destroy', destroyListener);\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 }\n }\n}\n","/*\n * 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 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, Update} from '../../../layer';\nimport {ChatRights} from '../../../lib/appManagers/appChatsManager';\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, {i18n, join, LangPackKey} from '../../../lib/langPack';\nimport rootScope from '../../../lib/rootScope';\nimport CheckboxField from '../../checkboxField';\nimport PopupPickUser from '../../popups/pickUser';\nimport Row, {CreateRowFromCheckboxField} from '../../row';\nimport SettingSection from '../../settingSection';\nimport {SliderSuperTabEventable} from '../../sliderTab';\nimport {toast} from '../../toast';\nimport AppUserPermissionsTab from './userPermissions';\n\nexport class ChatPermissions {\n public v: Array<{\n flags: ChatRights[],\n text: LangPackKey,\n exceptionText: LangPackKey,\n checkboxField?: CheckboxField,\n }>;\n private toggleWith: Partial<{[chatRight in ChatRights]: ChatRights[]}>;\n\n constructor(private options: {\n chatId: ChatId,\n listenerSetter: ListenerSetter,\n appendTo: HTMLElement,\n participant?: ChannelParticipant.channelParticipantBanned\n }, private managers: AppManagers) {\n this.construct();\n }\n\n public async construct() {\n this.v = [\n {flags: ['send_messages'], text: 'UserRestrictionsSend', exceptionText: 'UserRestrictionsNoSend'},\n {flags: ['send_media'], text: 'UserRestrictionsSendMedia', exceptionText: 'UserRestrictionsNoSendMedia'},\n {flags: ['send_stickers', 'send_gifs'], text: 'UserRestrictionsSendStickers', exceptionText: 'UserRestrictionsNoSendStickers'},\n {flags: ['send_polls'], text: 'UserRestrictionsSendPolls', exceptionText: 'UserRestrictionsNoSendPolls'},\n {flags: ['embed_links'], text: 'UserRestrictionsEmbedLinks', exceptionText: 'UserRestrictionsNoEmbedLinks'},\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 this.toggleWith = {\n 'send_messages': ['send_media', 'send_stickers', 'send_polls', 'embed_links']\n };\n\n const options = this.options;\n const chat = await this.managers.appChatsManager.getChat(options.chatId) as Chat.chat | Chat.channel;\n const defaultBannedRights = chat.default_banned_rights;\n const rights = options.participant ? combineParticipantBannedRights(chat as Chat.channel, options.participant.banned_rights) : defaultBannedRights;\n\n const restrictionText: LangPackKey = options.participant ? 'UserRestrictionsDisabled' : 'EditCantEditPermissionsPublic';\n for(const info of this.v) {\n const mainFlag = info.flags[0];\n const row = CreateRowFromCheckboxField(\n info.checkboxField = new CheckboxField({\n text: info.text,\n checked: hasRights(chat, mainFlag, rights),\n restriction: true,\n listenerSetter: options.listenerSetter\n })\n );\n\n if((\n options.participant &&\n defaultBannedRights.pFlags[mainFlag 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.checkboxField.input.disabled = true;\n\n /* options.listenerSetter.add(info.checkboxField.input)('change', (e) => {\n if(!e.isTrusted) {\n return;\n }\n\n cancelEvent(e);\n toast('This option is disabled for all members in Group Permissions.');\n info.checkboxField.checked = false;\n }); */\n\n attachClickEvent(info.checkboxField.label, (e) => {\n toast(I18n.format(restrictionText, true));\n }, {listenerSetter: options.listenerSetter});\n }\n\n if(this.toggleWith[mainFlag]) {\n options.listenerSetter.add(info.checkboxField.input)('change', () => {\n if(!info.checkboxField.checked) {\n const other = this.v.filter((i) => this.toggleWith[mainFlag].includes(i.flags[0]));\n other.forEach((info) => {\n info.checkboxField.checked = false;\n });\n }\n });\n }\n\n options.appendTo.append(row.container);\n }\n }\n\n public takeOut() {\n const rights: ChatBannedRights = {\n _: 'chatBannedRights',\n until_date: 0x7FFFFFFF,\n pFlags: {}\n };\n\n for(const info of this.v) {\n const banned = !info.checkboxField.checked;\n if(banned) {\n info.flags.forEach((flag) => {\n // @ts-ignore\n rights.pFlags[flag] = true;\n });\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 new 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.getChannelParticipant(this.chatId, peerId) as any;\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.v.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 setSubtitle(dom, participant);\n\n // dom.titleSpan.innerHTML = 'Chinaza Akachi';\n // dom.lastMessageSpan.innerHTML = 'Can Add Users and Pin Messages';\n };\n\n // this.listenerSetter.add(rootScope)('updateChannelParticipant', (update: Update.updateChannelParticipant) => {\n // const needAdd = update.new_participant?._ === 'channelParticipantBanned' && !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, update.new_participant as ChannelParticipant.channelParticipantBanned);\n // }\n\n // if(update.prev_participant?._ !== 'channelParticipantBanned') {\n // ++exceptionsCount;\n // }\n // } else {\n // if(li) {\n // li.remove();\n // }\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';\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_messages',\n 'send_media',\n 'send_stickers',\n 'send_polls',\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 new 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';\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 scrollable: this.scrollable,\n onChangeTab: (mediaTab) => {\n const timeout = mediaTab.type === 'members' && rootScope.settings.animationsEnabled ? 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 new 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 new 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 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 && rootScope.settings.animationsEnabled && 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(!rootScope.settings.animationsEnabled || !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 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 type LazyLoadQueue from './lazyLoadQueue';\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\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) => 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 const status = getUserStatusString(await this.managers.appUsersManager.getUser(element.id));\n replaceContent(element.dom.lastMessageSpan, status);\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 {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 (base as SortedUser).dom = dom;\n return base as SortedUser;\n },\n updateElementWith: fastRaf,\n updateListWith: async(callback) => {\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 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: () => 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?.();\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(Math.max(0, e.button ?? 0) !== 0) {\n return;\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 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';\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(!rootScope.settings.animationsEnabled || (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 {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}: {\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}): 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 (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 }, rootScope.settings.animationsEnabled ? 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} & 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, middleware, lazyLoadQueue, customEmojiSize, animationGroup} = 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 {\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(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 const anchorHTML = wrapRichText(action.domain, {\n entities: [{\n _: 'messageEntityUrl',\n length: action.domain.length,\n offset: 0\n }]\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 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 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({message: (message as Message.messageService), plain});\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","/*\n * 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';\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 | VideoSize,\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) && rootScope.settings.animationsEnabled && !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 {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';\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}: {\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 | VideoSize,\n isOut?: boolean,\n noPremium?: boolean,\n withLock?: boolean,\n relativeEffect?: boolean,\n loopEffect?: boolean,\n isCustomEmoji?: boolean,\n syncedVideo?: boolean\n}) {\n div = Array.isArray(div) ? div : [div];\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 div.forEach((div) => {\n div.dataset.docId = '' + doc.id;\n if(emoji) {\n div.dataset.stickerEmoji = emoji;\n }\n\n div.classList.add('media-sticker-wrapper');\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(rootScope.settings.animationsEnabled && !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: !!(!emoji || isCustomEmoji) && 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 });\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') && rootScope.settings.animationsEnabled;\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'))) && rootScope.settings.animationsEnabled;\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(media as HTMLVideoElement, group, undefined, middleware);\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 cancelEvent(e);\n if(playing) {\n const a = document.createElement('a');\n a.onclick = () => {\n hideToast();\n new 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()) {\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 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 });\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}: {\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 | VideoSize,\n withRandomOffset?: boolean,\n relativeEffect?: boolean,\n loopEffect?: boolean\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 };\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 }).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(media as HTMLVideoElement, group);\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 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 {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?: VideoSize,\n searchContext?: MediaSearchContext,\n managers?: AppManagers,\n noAutoplayAttribute?: boolean\n}) {\n const autoDownloadSize = autoDownload?.video;\n let noAutoDownload = autoDownloadSize === 0;\n const isAlbumItem = !(boxWidth && boxHeight);\n const canAutoplay = /* doc.sticker || */(\n (\n doc.type !== 'video' || (\n doc.size <= MAX_VIDEO_AUTOPLAY_SIZE &&\n !isAlbumItem\n )\n ) && (doc.type === 'gif' ? rootScope.settings.autoPlay.gifs : rootScope.settings.autoPlay.videos)\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 (divRound as any).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(video, group);\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 /* 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","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\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) {\n const {dateEl, timeEl} = formatFullSentTimeRaw(timestamp, {\n capitalize: true\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\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 add(CLICK_EVENT_NAME, callback, options);\n\n // @ts-ignore\n return () => remove(CLICK_EVENT_NAME, callback, options);\n}\n\nexport 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 contextMenuController from '../contextMenuController';\nimport ListenerSetter from '../listenerSetter';\nimport {getMiddleware} from '../middleware';\nimport positionMenu from '../positionMenu';\nimport {attachContextMenuListener} from './attachContextMenuListener';\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}: {\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}) {\n appendTo ??= document.body;\n\n attachListenerSetter ??= new ListenerSetter();\n const listenerSetter = new ListenerSetter();\n const middleware = getMiddleware();\n let element: HTMLElement;\n\n attachContextMenuListener({\n element: listenTo,\n callback: (e) => {\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 listenerSetter: attachListenerSetter\n });\n\n const cleanup = () => {\n listenerSetter.removeAll();\n middleware.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) => button?.verify ? 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('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 return {element, destroy};\n}\n","/*\n * 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, {EmoticonsDropdown} from '../../components/emoticonsDropdown';\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: () => new 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 || 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\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\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\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.innerHTML = 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","/*\n * 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 {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(rootScope.settings.animationsEnabled) {\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, detachClickEvent} 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';\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\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 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 || !rootScope.settings.animationsEnabled ? 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 detachClickEvent(window, this.onClickOut, {capture: true});\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';\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(!rootScope.settings.animationsEnabled || 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 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} 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(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(amount: number | string, currency: string, skipSymbol?: boolean) {\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 = 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","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 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","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';\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 new 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 new 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 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(!rootScope.settings.animationsEnabled) {\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(!rootScope.settings.animationsEnabled) {\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(rootScope.settings.animationsEnabled) {\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","import rootScope from '../../lib/rootScope';\n\nexport default function shake(element: HTMLElement) {\n if(!rootScope.settings.animationsEnabled) {\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 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};\nclass 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: MyDocument | MyPhoto = getMediaFromMessage(lastMessage);\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\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\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 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 {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 replaceContent from '../../helpers/dom/replaceContent';\nimport {Middleware} from '../../helpers/middleware';\nimport limitSymbols from '../../helpers/string/limitSymbols';\nimport {Document, Message, MessageMedia, Photo, WebPage} 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],\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 {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 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 {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.firstChild) {\n this.innerHTML = '';\n } */\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.innerHTML = '';\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.innerHTML = 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 default function reflowScrollableElement(element: HTMLElement) {\n element.style.display = 'none';\n void element.offsetLeft; // reflow\n element.style.display = '';\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\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};\n\nexport type InternalLink = InternalLink.InternalLinkMessage | InternalLink.InternalLinkPrivatePost | InternalLink.InternalLinkStickerSet | InternalLink.InternalLinkJoinChat | InternalLink.InternalLinkVoiceChat | InternalLink.InternalLinkUserPhoneNumber | InternalLink.InternalLinkInvoice | InternalLink.InternalLinkEmojiSet;\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 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 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\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};\n","/*\n * 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 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';\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 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 = 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 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\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","export default function accumulate(arr: number[], initialValue: number) {\n return arr.reduce((acc, value) => acc + value, initialValue);\n}\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","const NBSP = '‎';\nexport default NBSP;\n","/*\n * 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 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 new 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 new 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 new 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 new 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 = new 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","/*\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 {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: Photo.photo | Document.document = getMediaFromMessage(message);\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","/*\n * 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, detachClickEvent, 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';\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 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.innerHTML = 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.innerHTML = '';\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 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(!rootScope.settings.animationsEnabled) {\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 attachClickEvent(this, this.clickHandler);\n } else {\n detachClickEvent(this, this.clickHandler);\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 {Chat as MTChat, ChatInvite, 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, detachClickEvent, 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 confirmationPopup from '../confirmationPopup';\nimport wrapPeerTitle from '../wrappers/peerTitle';\nimport {PopupPeerCheckboxOptions} from '../popups/peer';\nimport toggleDisability from '../../helpers/dom/toggleDisability';\nimport {copyTextToClipboard} from '../../helpers/clipboard';\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 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 any).message = message;\n (element as any).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)('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 return {bubble: result.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 = (await this.chat.getMessage(mid)) as Message.message;\n\n MessageRender.setReply({\n chat: this.chat,\n bubble,\n message\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(rootScope.settings.animationsEnabled) {\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 hasRights = await this.chat.canSend();\n\n if(hadRights !== hasRights) {\n const callbacks = await Promise.all([\n this.finishPeerChange(),\n this.chat.input.finishPeerChange()\n ]);\n\n callbacks.forEach((callback) => callback());\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 new 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 new 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 new PopupStickers(doc.stickerSetInput).show();\n }\n\n return;\n }\n\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) {\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(message, targets[idx].element, 0, true, targets.slice(0, idx), targets.slice(idx + 1));\n\n // appMediaViewer.openMedia(message, target as HTMLImageElement);\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 new 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 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 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 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\n if(!cached && !samePeer) {\n await m(this.chat.finishPeerChange(isTarget, isJump, lastMsgId, startParam));\n this.scrollable.container.textContent = '';\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(isTarget, isJump, lastMsgId, startParam)); // * костыль\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([setPeerPromise, getHeavyAnimationPromise()]);\n afterSetPromise.then(() => { // check whether list isn't full\n scrollable.checkForTriggers();\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 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 middleware = this.getMiddleware();\n const peerId = this.peerId;\n\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 // 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.innerHTML = '';\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 s.append(await wrapMessageActionTextNew({\n message,\n ...wrapOptions\n }));\n }\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[];\n if(isMessage) {\n if(groupedId && albumMustBeRenderedFull) {\n const t = 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 const richText = wrapRichText(messageMessage, {\n entities: totalEntities,\n passEntities: this.passEntities,\n loadPromises,\n lazyLoadQueue: this.lazyLoadQueue,\n customEmojiSize,\n middleware,\n animationGroup: this.chat.animationGroup\n });\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 = new 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 });\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 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: richText\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 // /////this.log('message to render hidden', message);\n title = document.createElement('span');\n setInnerHTML(title, wrapEmojiText(fwdFrom.from_name));\n title.classList.add('peer-title');\n // title = fwdFrom.from_name;\n bubble.classList.add('hidden-profile');\n } else {\n title = new PeerTitle({peerId: fwdFromId || message.fromId, withPremiumIcon: !isForward, wrapOptions}).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(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 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 });\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 new 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 /**\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 && rootScope.settings.animationsEnabled/* && 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 setInnerHTML from '../../helpers/dom/setInnerHTML';\nimport {MediaSizeType} from '../../helpers/mediaSizes';\nimport {Message} from '../../layer';\nimport {AppManagers} from '../../lib/appManagers/managers';\nimport {MediaSearchContext} from '../appMediaPlaybackController';\nimport Chat from '../chat/chat';\nimport LazyLoadQueue from '../lazyLoadQueue';\nimport wrapDocument from './document';\n\nexport default async function wrapGroupedDocuments({albumMustBeRenderedFull, message, bubble, messageDiv, chat, loadPromises, autoDownloadSize, lazyLoadQueue, searchContext, useSearch, sizeType, managers, fontWeight, fontSize, richTextFragment}: {\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}) {\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 });\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 setInnerHTML(messageDiv, richTextFragment);\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 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 = new 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\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 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","/*\n * 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 {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 new 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';\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}) => {\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 replaceContent(dom.lastMessageSpan, getUserStatusString(await this.managers.appUsersManager.getUser(peerId.toUserId())));\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 {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 rootScope.settings.animationsEnabled && !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 ...options\n });\n } else {\n let isFirst = true;\n wrapSticker({\n doc: reaction.appear_animation,\n div: appearWrapper,\n play: true,\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 ...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} 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 from '../../lib/appManagers/appDownloadManager';\nimport {SERVICE_PEER_ID} from '../../lib/mtproto/mtproto_config';\nimport {MessagesStorageKey} 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';\n\nexport default class ChatContextMenu {\n private buttons: (ButtonMenuItemOptions & {verify: () => boolean | Promise, notDirect?: () => boolean, withSelection?: true, isSponsored?: true, localName?: 'views' | 'emojis'})[];\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 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\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 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\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 if(this.isSponsored) {\n return buttons.filter((button) => {\n return button.isSponsored;\n });\n } else {\n return filterAsync(buttons, async(button) => {\n let good: boolean;\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\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.innerHTML);\n },\n verify: () => this.isUsernameTarget,\n withSelection: true\n }, {\n icon: 'copy',\n text: 'Text.Context.Copy.Hashtag',\n onClick: () => {\n copyTextToClipboard(this.target.innerHTML);\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: () => {\n appDownloadManager.downloadToDisc({media: getMediaFromMessage(this.message)});\n },\n verify: () => {\n if(!canSaveMessageMedia(this.message) || this.noForwards) {\n return false;\n }\n\n const isPhoto: boolean = !!((this.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 = ((this.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 = !!IS_TOUCH_SUPPORTED;\n\n if(isGoodType) hasTarget ||= !!findUpClassName(this.target, 'document') || !!findUpClassName(this.target, 'audio') || !!findUpClassName(this.target, 'media-sticker-wrapper') || !!findUpClassName(this.target, 'media-photo') || !!findUpClassName(this.target, 'media-video');\n\n return isGoodType && hasTarget;\n }\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: 'flag',\n text: 'ReportChat',\n onClick: () => {\n new 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) {\n this.chat.appImManager.setInnerPeer({\n peerId: this.viewerPeerId\n });\n } else if(this.canOpenReactedList) {\n new 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 new PopupSponsored();\n },\n verify: () => false,\n isSponsored: true\n }, {\n // icon: 'smile',\n text: 'Loading',\n onClick: () => {\n this.emojiInputsPromise.then((inputs) => {\n new PopupStickers(inputs, true).show();\n });\n },\n verify: () => !!this.getUniqueCustomEmojisFromMessage().length,\n notDirect: () => true,\n localName: 'emojis'\n }];\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 if(fakeText) {\n fakeText.remove();\n }\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.readParticipants.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 new 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 new PopupPinMessage(this.peerId, this.mid);\n };\n\n private onUnpinClick = () => {\n new 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 new PopupForward({\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 new PopupDeleteMessages(this.peerId, this.isTargetAGroupedItem ? [this.mid] : await this.chat.getMidsByMid(this.mid), this.chat.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 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 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 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","/*\n * 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) {\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 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 = 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\nimport type Chat from '../chat/chat';\nimport type {SendFileDetails} from '../../lib/appManagers/appMessagesManager';\nimport PopupElement from '.';\nimport Scrollable from '../scrollable';\nimport {toast} 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 {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';\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 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 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: () => this.hasAnyMedia() && this.willAttach.type === 'document'\n }, {\n icon: 'document',\n text: 'SendAsFile',\n onClick: () => this.changeType('document'),\n verify: () => this.files.length === 1 && this.willAttach.type !== 'document'\n }, {\n icon: 'document',\n text: 'SendAsFiles',\n onClick: () => this.changeType('document'),\n verify: () => this.files.length > 1 && this.willAttach.type !== 'document'\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() {\n const [media, files] = partition(this.willAttach.sendFileDetails, (d) => MEDIA_MIME_TYPES_SUPPORTED.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 send(force = false) {\n if(this.chat.type === 'scheduled' && !force) {\n this.chat.input.scheduleSending(() => {\n this.send(true);\n });\n\n return;\n }\n\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 willAttach = this.willAttach;\n willAttach.isMedia = willAttach.type === 'media' || undefined;\n const {sendFileDetails, isMedia} = willAttach;\n\n const {peerId, input} = this.chat;\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 = file.type.startsWith('audio/');\n if(isPhoto || isAudio || file.size < 20e6) {\n params.objectURL ||= await apiManagerProxy.invoke('createObjectURL', file);\n }\n\n let img: HTMLImageElement;\n if(isPhoto) {\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 const doc = {\n _: 'document',\n file: file,\n file_name: file.name || '',\n size: file.size,\n type: isPhoto ? 'photo' : 'doc'\n } as MyDocument;\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 * 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, detachClickEvent} 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;\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 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(list, onClick);\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';\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 && this.controller.addHelper(this);\n }\n\n public toggleListNavigation(enabled: boolean) {\n if(enabled) {\n this.attach && this.attach();\n } else {\n this.detach && this.detach();\n }\n }\n\n protected onVisible = () => {\n if(this.detach) { // it can be so because 'visible' calls before animation's end\n this.detach();\n }\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.innerHTML = '';\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 if(this.detach) { // force detach here\n this.detach();\n }\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: rootScope.settings.animationsEnabled && !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 if(this.lazyLoadQueue) {\n this.lazyLoadQueue.clear();\n }\n\n preloadAnimatedEmojiSticker(emoticon);\n this.managers.appStickersManager.getStickersByEmoticon(emoticon)\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.popupSticker.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.innerHTML = '';\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.innerHTML = '';\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';\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: (peerId: PeerId, username: string, query: string) => 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) => {\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 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\n if(this.gifsMasonry) {\n this.gifsMasonry.detach();\n }\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}\n","/*\n * 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 {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(rootScope.settings.animationsEnabled) {\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 {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\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';\n\nconst RECORD_MIN_TIME = 500;\nconst POSTING_MEDIA_NOT_ALLOWED = 'Posting media content isn\\'t allowed in this group.';\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 private 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 private 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\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 public constructPeerHelpers() {\n this.replyElements.container = document.createElement('div');\n this.replyElements.container.classList.add('reply-wrapper');\n\n this.replyElements.iconBtn = ButtonIcon('');\n this.replyElements.cancelBtn = ButtonIcon('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 = ButtonIcon('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 = ButtonIcon('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 = ButtonIcon('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 this.attachMenuButtons = [{\n icon: 'image',\n text: 'Chat.Input.Attach.PhotoOrVideo',\n onClick: () => {\n this.fileInput.value = '';\n const accept = [...MEDIA_MIME_TYPES_SUPPORTED].join(', ');\n this.fileInput.setAttribute('accept', accept);\n this.willAttachType = 'media';\n this.fileInput.click();\n },\n verify: () => this.chat.canSend('send_media')\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_media')\n }, {\n icon: 'poll',\n text: 'Poll',\n onClick: () => {\n PopupElement.createPopup(PopupCreatePoll, this.chat).show();\n },\n verify: () => (this.chat.peerId.isAnyChat() || this.chat.isBot) && this.chat.canSend('send_polls')\n }];\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 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 = ButtonIcon('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 = ButtonIcon('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 new 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 new 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(startParam?: string) {\n const peerId = this.chat.peerId;\n\n const {forwardElements, btnScheduled, replyKeyboard, sendMenu, goDownBtn, chatInput, botCommandsToggle} = this;\n\n const previousSendAs = this.sendAs;\n const sendAs = this.createSendAs();\n\n const [\n isBroadcast,\n canPinMessage,\n isBot,\n canSend,\n neededFakeContainer,\n ackedPeerFull,\n ackedScheduledMids,\n setSendAsCallback,\n filteredAttachMenuButtons\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(),\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 this.filterAttachMenuButtons()\n ]);\n\n const placeholderKey = this.messageInput ? await this.getPlaceholderKey() : 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 this.messageInputField?.onFakeInput();\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 const middleware = this.chat.bubbles.getMiddleware();\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 middleware = this.chat.bubbles.getMiddleware();\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 if(previousSendAs) {\n previousSendAs.destroy();\n }\n\n if(setSendAsCallback) {\n setSendAsCallback();\n }\n\n if(replyKeyboard) {\n replyKeyboard.setPeer(peerId);\n }\n\n if(sendMenu) {\n sendMenu.setPeerId(peerId);\n }\n\n if(this.messageInput) {\n this.updateMessageInput(canSend, placeholderKey, filteredAttachMenuButtons);\n this.messageInput.dataset.peerId = '' + peerId;\n }\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() {\n const {peerId, threadId, isForum} = this.chat;\n let key: LangPackKey;\n 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 i.compareAndUpdate({key});\n }\n\n private filterAttachMenuButtons() {\n if(!this.attachMenuButtons) return;\n return filterAsync(this.attachMenuButtons, (button) => {\n return button.verify();\n });\n }\n\n public updateMessageInput(canSend: boolean, placeholderKey: LangPackKey, visible: ChatInput['attachMenuButtons']) {\n const {chatInput, attachMenu, messageInput} = this;\n const {peerId, threadId} = this.chat;\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 this.updateMessageInputPlaceholder(placeholderKey);\n\n if(!canSend) {\n messageInput.contentEditable = 'inherit';\n } else {\n messageInput.contentEditable = 'true';\n this.setDraft(undefined, false);\n\n if(!messageInput.innerHTML) {\n this.messageInputField.onFakeInput();\n }\n }\n\n if(attachMenu) {\n attachMenu.toggleAttribute('disabled', !visible.length);\n attachMenu.classList.toggle('btn-disabled', !visible.length);\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.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 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 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 if(this.appImManager.markupTooltip) {\n this.appImManager.markupTooltip.setActiveMarkupButton();\n }\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 private 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 // console.log('messageInput url:', url);\n\n if(this.lastUrl !== url) {\n this.lastUrl = url;\n // this.willSendWebPage = null;\n const promise = this.getWebPagePromise = this.managers.appWebPagesManager.getWebPage(url).then((webpage) => {\n if(this.getWebPagePromise === promise) this.getWebPagePromise = undefined;\n if(this.lastUrl !== url) return;\n if(webpage._ === 'webPage') {\n // console.log('got webpage: ', webpage);\n\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 if(this.appImManager.markupTooltip) {\n this.appImManager.markupTooltip.hide();\n }\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) {\n // document.execCommand('styleWithCSS', false, 'true');\n setTimeout(() => {\n if(document.activeElement === this.messageInput) {\n this.resetCurrentFontFormatting();\n }\n }, 0);\n // document.execCommand('styleWithCSS', false, 'false');\n }\n } else {\n const time = Date.now();\n if((time - this.lastTimeType) >= 6000) {\n this.lastTimeType = time;\n this.managers.appMessagesManager.setTyping(this.chat.peerId, {_: 'sendMessageTypingAction'}, undefined, this.chat.threadId);\n }\n\n if(this.botCommands) {\n this.botCommands.toggle(true);\n }\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 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 ? {_: 'messageEntityCustomEmoji', document_id: emoji.docId, length: emoji.emoji.length, offset: 0} : 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 if(value === undefined) {\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) {\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 &&\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 foundHelper = this.checkInlineAutocomplete(value, foundHelper);\n\n this.autocompleteHelperController.hideOtherHelpers(foundHelper);\n }\n\n private checkInlineAutocomplete(value: string, foundHelper?: AutocompleteHelper): AutocompleteHelper {\n let needPlaceholder = false;\n\n const setPreloaderShow = (show: boolean) => {\n if(!this.btnPreloader) {\n return;\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 = ButtonIcon('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).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 if(isAnyChat && !(await this.chat.canSend('send_media'))) {\n toast(POSTING_MEDIA_NOT_ALLOWED);\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 new 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 private 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 new 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 = new 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(this.messageInput, 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 new 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 toast(POSTING_MEDIA_NOT_ALLOWED);\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 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 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.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 = ButtonIcon((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 // public saveScroll() {\n // this.scrollTop = this.chat.bubbles.scrollable.container.scrollTop;\n // this.scrollOffsetTop = this.chatInput.offsetTop;\n // }\n\n // public restoreScroll() {\n // if(this.chatInput.style.display) return;\n // //console.log('input resize', offsetTop, this.chatInput.offsetTop);\n // let newOffsetTop = this.chatInput.offsetTop;\n // let container = this.chat.bubbles.scrollable.container;\n // let scrollTop = container.scrollTop;\n // let clientHeight = container.clientHeight;\n // let maxScrollTop = container.scrollHeight;\n\n // if(newOffsetTop < this.scrollOffsetTop) {\n // this.scrollDiff = this.scrollOffsetTop - newOffsetTop;\n // container.scrollTop += this.scrollDiff;\n // } else if(scrollTop !== this.scrollTop) {\n // let endDiff = maxScrollTop - (scrollTop + clientHeight);\n // if(endDiff < this.scrollDiff/* && false */) {\n // //container.scrollTop -= endDiff;\n // } else {\n // container.scrollTop -= this.scrollDiff;\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 {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 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","// 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.innerHTML = 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 {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();\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 media: undefined,\n streamable: undefined,\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(media);\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","/*\n * 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';\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 new PopupPinMessage(this.chat.peerId, this.pinnedMid, true);\n } else {\n new 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';\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 new PopupPickUser({\n peerTypes: ['dialogs', 'contacts'],\n onSelect: (peerId) => {\n return new Promise((resolve, reject) => {\n new 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 chatRightsAction: 'send_messages',\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: '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 new 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 new 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 new 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(isTarget: boolean) {\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 [isBroadcast, isAnyChat, chat, _, setTitleCallback, setStatusCallback, state] = 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';\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(rootScope.settings.animationsEnabled) {\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) {\n return this.setPeer({\n peerId: this.peerId,\n threadId: this.threadId,\n lastMsgId: messageId\n });\n }\n\n public async finishPeerChange(isTarget: boolean, isJump: boolean, lastMsgId: number, startParam?: string) {\n if(this.peerChanged) return;\n\n const peerId = this.peerId;\n this.peerChanged = true;\n this.wasAlreadyUsed = true;\n\n const middleware = this.bubbles.getMiddleware();\n\n this.cleanup(false);\n\n const sharedMediaTab = this.sharedMediaTab;\n\n const callbacksPromise = Promise.all([\n this.topbar.finishPeerChange(isTarget),\n this.bubbles.finishPeerChange(),\n this.input.finishPeerChange(startParam),\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 };\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","/*\n * 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 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: rootScope.settings.animationsEnabled && !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 new 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 new 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 new 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 ? .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',\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 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 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} 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 {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';\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};\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 = new 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 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 = new 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 new 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 ([\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 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: {thread?: string, comment?: string} | {comment?: string, start?: string}\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 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 };\n } else {\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 };\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 }\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 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 new 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 new 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;\n rootScope.addEventListener('app_config', (_appConfig) => {\n appConfig = _appConfig;\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 if(!appConfig.autologin_token || !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', appConfig.autologin_token);\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(rootScope.settings.animationsEnabled && 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 // 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) && target.tagName !== 'INPUT') {\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 e.target !== chat.input.messageInput &&\n target.tagName !== 'INPUT' &&\n !target.isContentEditable &&\n !IS_TOUCH_SUPPORTED &&\n (!mediaSizes.isMobile || this.tabId === APP_TABS.CHAT) &&\n !chat.selection.isSelecting &&\n !chat.input.recording\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 });\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 });\n break;\n }\n\n case INTERNAL_LINK_TYPE.EMOJI_SET:\n case INTERNAL_LINK_TYPE.STICKER_SET: {\n new 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 new 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 new PopupPayment(undefined, inputInvoice, paymentForm);\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', !rootScope.settings.animationsEnabled);\n document.body.classList.toggle('animation-level-1', false);\n document.body.classList.toggle('animation-level-2', rootScope.settings.animationsEnabled);\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 }, rootScope.settings.animationsEnabled ? 250 : 0, false, true);\n\n if(lottieLoader.setLoop(rootScope.settings.stickers.loop)) {\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(rootScope.settings.animationsEnabled && 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 _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 = types.filter((t) => MEDIA_MIME_TYPES_SUPPORTED.has(t)).length;\n // const foundDocuments = types.length - foundMedia;\n\n this.log('drag files', types);\n\n if(newMediaPopup) {\n newMediaPopup.appendDrops(_dropsContainer);\n\n if(types.length || force) {\n _drops.push(new ChatDragAndDrop(_dropsContainer, {\n header: 'Preview.Dragging.AddItems',\n headerArgs: [types.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(types.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 && !foundDocuments) || force) {\n if(foundMedia || 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 = rootScope.settings.animationsEnabled ? doubleRaf() : Promise.resolve();\n if(\n prevTabId !== undefined &&\n prevTabId !== id &&\n rootScope.settings.animationsEnabled &&\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\nconst appImManager = new AppImManager();\nMOUNT_CLASS_TO && (MOUNT_CLASS_TO.appImManager = appImManager);\nexport default appImManager;\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, Message, MessageAction, MessageExtendedMedia, MessageMedia, Photo, WebPage} from '../../../../layer';\n\nexport default function getMediaFromMessage(message: Message) {\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 }\n\n return media as Photo.photo | Document.document;\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","/*\n * 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';\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(this, this.renderer.animationGroup, undefined, true);\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\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(element, element.renderer.animationGroup, undefined, true);\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 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.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\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, {AnimationItemGroup} 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\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 setLoop(loop: boolean) {\n let changed = false;\n for(const i in this.players) {\n const player = this.players[i];\n if(player._loop && player.loop !== loop) {\n changed = true;\n player.loop = loop;\n\n // if(player._autoplay && player.autoplay !== player._autoplay) {\n player.autoplay = player._autoplay;\n // }\n }\n }\n\n return changed;\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(player, group, undefined, middleware);\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 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};\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\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\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 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","observeElement","controlled","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","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","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","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","spoiler","HTMLAnchorElement","contains","onclick","getAttribute","includes","capture","click","getScheduledMessageByPeer","setCaption","html","entities","totalEntities","firstElementChild","fromRight","prevTargets","nextTargets","setMoverPromise","fwd_from","from_name","noForwards","isServiceMessage","cantForwardMessage","canForward","cantDownloadMessage","download","canDeleteMessage","hide","button","_openMedia","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","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","moversContainer","isGesturingNow","lastGestureTime","Date","now","clampZoomDebounced","isZooming","initialContentRect","getBoundingClientRect","onSwipeReset","draggingType","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","ctrlKeyDown","addZoomStep","ctrlKey","metaKey","onKeyUp","rootScope","log","logger","cancelable","lazyLoadQueue","overlaysDiv","mainDiv","topbar","topbarLeft","onlyMobile","authorRight","avatarEl","nameEl","buttonsDiv","concat","noRipple","rangeSelector","step","withTransition","setHandlers","onScrub","onMouseUp","main","innerHTML","onLoadedMore","setNewMover","moveLength","adjustPosition","xDiff","yDiff","setLastGestureTime","swipeHandler","onReset","onFirstSwipe","onSwipe","cancelDrag","onDoubleClick","centerX","centerY","ZOOM_INITIAL_VALUE","changeZoomByPosition","verifyTouchTarget","cursor","changeZoom","enable","isVisible","auto","mousedown","zoomValue","setProgress","videoPlayer","lockControls","addZoom","getZoomBounce","left","right","top","bottom","btnMenuToggle","buttonOptions","direction","Promise","reject","navigationItem","appNavigationController","clear","setMoverToTarget","onAnimationEnd","appMediaViewer","removeGlobalListeners","toggleOverlay","active","toggleGlobalListeners","setGlobalListeners","removeCenterFromMover","wasActive","delay","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","dataset","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","timestamp","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","cancellableFullPromise","attachPromise","haveImage","fullImage","setManual","onPopState","hash","location","state","debug","isPossibleSwipe","currentHash","overriddenHash","overrideHash","onHashChange","pushState","navigations","manual","handleItem","onEscape","back","onTouchStart","touches","passive","options","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","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","replaceChildren","recentSearch","isUser","getUserStatusString","toUserId","getTopPeers","peers","people","subtitleEl","loadMembers","renderParticipants","membersList","rippleEnabled","li","findUpTag","DIALOG_LIST_ELEMENT_TAG","participant","getParticipantPeerId","isAnyChat","deleted","appChatsManager","isChannel","LOAD_COUNT","appProfileManager","getChannelParticipants","getChatFull","chatFull","loadType","justLoad","used","slicedLength","ids","notFilteredMessages","m","checkForTriggers","getSearch","nextRate","next_rate","loadFirstTime","filters","counters","canViewMembers","getSearchCounters","firstMediaTab","counter","c","membersTab","loadFirstTimePromise","toLoad","t","findAndSplice","setHours","setDate","dateTimestamp","getTime","containers","month","getFullYear","year","dateElement","haveTimestamps","getObjectKeysAndSort","positionElementByIndex","chatId","isBroadcast","hasRights","isForum","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","peerIds","splitUp","notRendered","filterPeerTypeBy","section","innerContainer","topContainer","selectedContainer","selectedScrollable","sectionNameLangPackKey","noShadow","checkbox","checked","debouncedInput","appendTo","getResultsPromise","onFirstRender","renderSaved","testSelfSearch","getTempId","getMoreDialogs","archived","pageCount","skipMigrated","newOffsetIndex","chatRightsAction","filterByRights","isEnd","getMoreContacts","isGlobalSearch","searchResult","resultPeerIds","arr","getMoreChannelParticipants","channelParticipants","q","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","durationStr","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","onTimeUpdate","throttledTimeUpdate","addAudioListener","readyPromise","mousemove","scrub","targetTouches","pageX","scrubTime","wrapVoiceMessage","descriptionEl","audioAttribute","parts","titleEl","middleEllipsisEl","fontSize","sizeType","subtitleDiv","launched","progressLine","lastChild","wrapAudio","audioTimeDiv","HAVE_CURRENT_DATA","onTypeDisconnect","getTimeStr","hadSearchContext","useSearch","imgs","autoDownload","shouldPlay","onDownloadInit","pauseListener","notifyAll","done","total","cancel","Error","playListener","setDownloadFunction","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","ButtonMenuItem","separator","iconDoc","noCheckboxClickListener","textElement","textArgs","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","ChatBackgroundGradientRenderer","_width","_height","_tails","_scrollTails","_curve","_positions","_phases","onWheel","_animatingToNextPosition","_scrollDelta","deltaY","_onWheelRAF","drawOnWheel","floor","ceil","changeTailAndDraw","drawNextPositionAnimated","getProgress","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","cancelAnimationFrame","colors","alpha","_canvas","fillStyle","fillRect","toNextPosition","tails","nextPhaseOnIdx","inc","curves","last","scrollAnimate","createCanvas","gradientRenderer","accumulateMapSet","reduce","acc","AppSelection","selectedMids","onMouseDown","targetLookupClassName","verifyTarget","selecting","firstTarget","processElement","checkBetween","isInDOM","seenSet","seenLength","findUpAsChild","elementsBetween","getElementsBetween","toggleByMid","canceledSelection","onMouseMove","getElementFromTarget","verifyMouseMoveTarget","removeManual","listenElement","documentListenerOptions","first","firstRect","lastRect","isHigher","lookupBetweenParentClassName","lookupBetweenElementsQuery","firstIndex","lastIndex","doNotAnimate","onCancelSelection","toggleSelection","navigationType","random","attachListeners","selectedText","getSelection","toString","createRange","verifyTouchLongPress","isElementShouldBeSelected","appendCheckbox","hasCheckbox","getCheckboxInputFromElement","forwards","updateContainer","forceSelection","cantForward","cantDelete","cantSend","storageKey","cantForwardDeleteMids","onUpdateContainer","toggleCheckboxes","wasSelecting","blurActiveElement","toggleResult","onToggleSelection","updateElementSelection","toggleMid","unselect","deleteSelectedMids","SearchSelection","selectionCountEl","selectionGotoBtn","selectionContainer","BASE_CLASS","btnCancel","attachClickOptions","obj","fromPeerId","isPrivate","transitionElement","ChatSelection","chat","bubbles","recording","bubble","canSelectBubble","isGroupedBubbleSelected","getMidsFromGroupContainer","getBubbleGroupedItems","groupContainer","isGroupedSelected","isGroupedMidsSelected","mounted","getMountedBubble","needTranslateX","widthFrom","widthTo","center","selectionInputWrapper","selectionSendNowBtn","selectionLeft","selectionRight","translateButtonsX","inputContainer","toggleAttribute","skippedMids","isGrouped","groupedCheckboxInput","CheckboxField","restriction","toggleDisability","stateKey","stateValues","stateValue","setValueSilently","box","checkSvg","bg","border","withRipple","withHover","Event","disable","CodeInputField","assign","autocomplete","lastLength","setLabel","onFill","confirmationPopup","checkboxes","cancelButton","isCancel","countries","setCountries","country","hidden","default_name","localeCompare","VIRTUAL_COUNTRIES","CountryInputField","hidePicker","hideTimeout","selectWrapper","selectCountryByTarget","defaultName","phoneCodeEl","phoneCode","countryCode","simulateInputEvent","lastCountrySelected","lastCountryCodeSelected","country_codes","_countryCode","country_code","onCountryChange","liMap","arrowDown","selectList","initSelect","noPhoneCodes","iso2","emoji","liArr","Infinity","spanEmoji","select","margin","mouseDownHandlerAttached","onKeyPress","_value","names","abbr","word","test","blur","selectCountryByIso2","countryName","DotRenderer","dpr","devicePixelRatio","prepare","dots","generateDot","adding","radius","Path2D","arc","PI","mOpacity","draw","dot","addOpacity","easedOpacity","globalAlpha","fill","renderFirstFrame","dotRenderer","EditPeer","_disabled","isChanged","uploadAvatar","changedLength","requiredLength","requiredValidLength","inputFields","isValid","required","handleChange","nextBtn","withoutAvatar","avatarElem","doNotEditAvatar","avatarEdit","_upload","popupOptions","lockWithPromise","unlockOnSuccess","GifsTab","gifsContainer","EmoticonsDropdown","masonry","EMOTICONSSTICKERGROUP","getGifs","docs","processInvisibleDiv","ANIMATIONGROUP","AppGifsTab","nextOffset","loadedAll","onGifsClick","fileId","inputSearch","gifsDiv","onCloseAfterTimeout","newSearch","gifBotPeerId","resolveUsername","appInlineBotsManager","getInlineResults","next_offset","AppStickersTab","setsDiv","listenTo","sticker","stickerSet","access_hash","appStickersManager","getStickerSet","toggleStickerSet","changed","installed_date","removeAttribute","renderFeatured","renderSet","header","countDiv","stickersDiv","stickerDiv","documents","withLock","getFeaturedStickers","coveredSets","filterRendered","forEachReverse","covered","searchStickerSets","scrollOptions","forceDuration","transitionFunction","ignoreOutClickClassName","tabId","onSelectTabClick","searchButton","emojiTab","deleteBtn","scrollTo","checkRights","tabsEl","tabsElements","canSendStickers","canSendGifs","canSendToPeer","stickersTab","gifsTab","whichChild","savedRange","getGoodRange","onOpened","unlock","refresh","onClosed","range","getSavedRange","setStartAfter","newRange","cloneRange","collapsed","node","endContainer","endOffset","newStartNode","previousSibling","nodeType","TEXT_NODE","nodeValue","ELEMENT_NODE","isContentEditable","selectNode","newOffset","setStart","deleteContents","HIDE_EMOJI_TAB","INIT_TAB_ID","lastMouseMoveEvent","mouseMoveEventAttached","isActive","onMouseOut","getElement","axis","clearDraft","silent","emoticonsDropdown","forceClose","addLazyLoadQueueRepeat","divs","intersector","getVisible","clearVisible","sel","rangeCount","activeElement","getRangeAt","menuOnClick","emoticons","menuScroll","prevTab","jumpedTo","getElementPosition","elementPosition","scrollToTab","scrollingToContent","stickyIntersector","stuck","getCategoryByContainer","which","getCategoryByMenuTab","additionalOffset","setActiveStatic","local","scrollLeft","clientWidth","sendDocId","loadedURLs","appendEmoji","unify","kek","getEmojiEntityFromEmoji","wrapSingleEmoji","fixEmoji","getEmojiFromElement","superEmoji","stickerEmoji","EMOJI_RECENT_ID","EMOJI_RECENT_CATEGORY","CUSTOM_EMOJI_RECENT_CATEGORY","EMOJI_CATEGORIES","sorted","category","order","EMOJI_ELEMENT_SIZE","EmojiTab","onCategoryVisibility","categoriesMap","renderer","newChildren","customEmojis","customEmojiElement","clearCanvas","onContentClick","isStandalone","langPackArguments","activeElements","menuInnerScroll","intersectionOptions","root","categoriesIntersector","menuOnClickResult","innerScrollWrapper","preparedMap","noRegularEmoji","emojis","titleLangPackKey","createLocalCategory","unified","addEmojiToCategory","batch","appEmojiManager","getRecentEmojis","stickerSetId","getLocalStickerSet","getCustomEmojis","recentCustom","mainSet","sets","recentCategory","categories","recentCustomCategory","CUSTOM_EMOJI_RECENT_ID","createRendererForCategory","paddingTop","toggleLocalCategory","resizeCategories","after","renderStickerSet","toggleCustomCategory","postponedEvent","positionCategory","toggleRenderers","ignore","ignoreSettingDimensions","setDimensionsFromRect","deleteCategory","isCategoryVisible","forceRender","closeScrollTop","createCategory","menuTabPadding","stickerEmojiRaw","setCategoryItemsHeight","getCustomCategory","hasPremium","canSeeCustomCategory","customEmojiSize","activeEmoji","spliceExceed","onLocalCategoryUpdate","LazyLoadQueueRepeat","parallelLimit","onVisibilityChange","elementsMap","queueItem","wasSeen","queue","indexOfAndSplice","setProcessQueueTimeout","SuperStickerRenderer","regularLazyLoadQueue","animated","checkAnimationContainer","processVisible","processInvisible","renderSticker","observeAnimated","unobserveAnimated","StickersTabCategory","noMenuTab","getContainerSize","getElementMediaSize","gapX","gapY","containerWidth","elementSize","itemsPerRow","rows","minHeight","EmoticonsTabC","categoryItemsClassName","args","postponedEvents","categoriesByMenuTabMap","localCategories","menuWrapper","isLocal","esgWidth","customProperties","observeStickyHeaderChanges","posItems","foundMenuScroll","posMenu","notMountedItems","notMountedMenus","itemsIdx","menuIdx","disconnect","StickersTab","setTyping","setFavedLimit","categoryAppendStickers","superStickerRenderer","clearCategoryItems","onCategoryStickers","stickers","deleteSticker","unshiftSticker","favedCategory","clearButton","titleLangKey","descriptionLangKey","langKey","clearRecentStickers","premiumCategory","apiManager","getLimit","getFavedStickersStickers","getRecentStickersStickers","getAllStickers","getPremiumStickers","isPremium","race","rendererLazyLoadQueue","faved","createStickersContextMenu","verifyRecent","unshiftRecentSticker","saveRecentSticker","deleteRecentSticker","generateDelimiter","delimiter","generateFakeIcon","isScam","LazyLoadQueueRepeat2","spliced","findAndSpliceAll","GifsMasonry","scrollPromise","processVisibleDiv","noInfo","noPreview","transitionTime","scrollableX","proxy","Proxy","apply","that","selectTarget","result1","canChange","mutateCallback","useStripe","indicator","currentIndicator","shiftLeft","insertRichTextAsHTML","wrappingForPeerId","some","createCustomEmojiRendererForInput","fragment","wrapDraftText","customEmojiRenderer","contentEditable","richInputHandler","customEmojiElements","ces","documentFragmentToHTML","pre","getCaretPosNew","createTextNode","collapse","removeAllRanges","addRange","onBeforeInput","inputType","execCommand","removeExtraBOMs","findUpAttribute","noLinebreaks","originalEvent","clipboardData","getData","usePlainText","filterEntity","curChild","nextSibling","richValue","getRichValueWithCaret","lines","textLength","lineIndex","line","nextLine","correctedText","entities2","parseEntities","mergeEntities","InputState","wrappingDraft","isSelectable","processCustomEmojisInInput","hasSet","connectedCallback","InputField","validate","maxLength","showLengthOn","canBeEdited","labelText","onInputCallbacks","isCollapsed","focusOnNext","clientX","isInputEmpty","inputMode","labelEl","showingLength","wasError","inputLength","isError","withLinebreaks","selectNodeContents","selectElementContents","labelOptions","fromSet","originalValue","isValidToChange","setDraftValue","setOriginalValue","setState","Valid","setError","InputSearch","prevValue","onClearClick","onClear","searchIcon","clearBtn","LazyLoadQueue","ignoreHeavyAnimation","getItem","addElement","LazyLoadQueueIntersector","inProcess","loadItem","intersectorTimeout","processQueue","MediaProgressLine","useTransform","onLoadedData","seek","progressRAF","setLoadProgress","onProgress","filledLoad","setSeekMax","buf","buffered","numRanges","nearestStart","end","percents","testQueue","pendingTest","setTestQueue","testElement","getElementWidth","mapped","firstTime","multiplier","font","textWidth","elementWidth","newElementWidth","widthChanged","smallerText","smallerWidth","smallerTextLength","half","half1","substr","half2","MiddleEllipsisElement","PasswordMonkey","passwordInputField","needFrame","noCache","currentFrame","setSpeed","helpers","onVisibilityClickAdditional","passwordVisible","setDirection","curFrame","TrackingMonkey","playAnimation","frame","idleAnimation","PasswordInputHelpers","onVisibilityClick","toggleVisible","stealthy","tabIndex","PasswordInputField","PeerProfileAvatars","avatar","avatars","draggable","loadCallback","intersectionObserver","loadCallbacks","addTab","gradient","info","arrowPrevious","arrowNext","checkScrollTop","SWITCH_ZONE","freeze","_e","clickX","toRight","cancelNextClick","lastDiffX","lastX","SCALE","TRANSLATE_TEMPLATE","addIndex","loadNearestToTarget","setPeer","backLimit","filterChatPhotosMessages","chat_photo","generateFakeAvatarMessage","activeTab","photo_id","setText","PeerProfile","noDelimiter","bio","contextMenu","subtitleLangKey","isAnonymous","getUserPhone","link","notifications","togglePeerMute","appNotificationsManager","isPeerLocalMuted","respectType","setPeerStatus","setMoreDetails","n","fillUsername","userId","self","fillUserPhone","setAvatar","setPeerStatusInterval","setInterval","needClear","callbacks","useWhitespace","ignoreSelf","clearSetMoreDetailsTimeout","canBeDetailed","createAvatar","_setAvatar","isTopic","oldAvatars","getUsernamesAlso","usernames","also","anchorCopy","getPeerActiveUsernames","formatUserPhone","fillNotifications","notificationsRow","fillName","withIcons","fillRows","fillProfileElements","cleaned","_setMoreDetails","peerFull","getMiddlewarePromise","getServerMessageId","about","getChat","exportedInvite","exported_invite","address","setMoreDetailsTimeout","isPeerRestricted","acknowledged","getProfileByPeerId","setPromise","cached","middlewarePromise","makeError","clearInterval","generateTitleIcons","noVerifiedIcon","noFakeIcon","noPremiumIcon","verified","use2","generateVerifiedIcon","fake","scam","premium","emojiStatus","emoji_status","generatePremiumIcon","weakMap","WeakMap","PeerTitle","setOptions","setHasInner","hasInner","fromName","limitSymbols","topic","forumTopic","getTopicIconPromise","icons","topicIcon","getPeerTitle","withPremiumIcon","inner","createDocumentFragment","PopupAvatar","closable","withConfirm","cropper","crop","removeHandlers","h6","btnClose","cropContainer","file","files","readBlobAsDataURL","contents","onload","originalImage","cropComponent","cropImage","event_state","cropLeft","cropTop","cropWidth","cropHeight","scaledRatio","overlayColor","CROPWIDTH","offsetHeight","CROPHEIGHT","updateCropSize","updateCropImage","startMoving","resizing","keyHandler","imgZoom","newWidth","newHeight","clientHeight","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","btnConfirm","toBlob","blob","darkenCanvas","onCrop","postCanvas","ctx","PopupDeleteDialog","onSelect","peerTitleElement","getDialogType","callbackLeave","flush","leave","flushHistory","callbackDelete","titleArgs","descriptionArgs","isDanger","titleLangArgs","descriptionLangArgs","PopupDeleteMessages","onConfirm","revoke","deleteScheduledMessages","deleteMessages","isMegagroup","_hasRights","canRevoke","PopupForward","peerIdMids","peerTypes","forwardMessages","DEFAULT_APPEND_TO","appendPopupTo","onFullScreenChange","PopupElement","reAppend","titleRaw","MANAGERS","confirmShortcutIsSendShortcut","withoutOverlay","overlayClosable","attachScrollableListeners","btnConfirmOnEnter","buttonsEl","buttonsElements","langArgs","POPUPS","setClassOn","attachBorderListeners","onContentUpdate","popup","popupConstructor","ctor","addCancelButton","pin","descriptionPremium","descriptionLocked","folders","P","_a","limitPremium","isLocked","limitContainer","hint","free","setHintActive","showLimitPopup","appConfig","premium_purchase_blocked","times","ONE_HOUR","PopupMute","time","mutePeer","muteUntil","radioForm","PopupPeer","noTitle","o","original","nextElementSibling","PopupPickUser","PopupSendNow","sendScheduledMessages","ANIMATION_GROUP","PopupStickers","stickerSetInput","isEmojis","onStickersClick","updateAdded","stickersFooter","onStickerSetUpdate","_set","updateButton","loadStickerSet","createStickerSetElements","headerRow","buttonRight","added","itemsContainer","setsPromises","isArray","firstSet","isStickerPack","onSend","containersPromises","docIds","toggleStickerSets","isAdd","buttonAppend","installed","ProgressivePreloader","detached","isUpload","attachMethod","loadFunc","constructContainer","bold","constructDownloadIcon","downloadSvg","cancelSvg","previousElementSibling","func","startTime","onEnd","notify","TRANSITION_TIME","addNotifyListener","useRafs","getTotalLength","strokeDasharray","putAvatar","renderThumbPromise","thumbImage","isFullLoaded","loadThumbPromise","stripped_thumb","getPreviewURLFromBytes","sequentialDom","renderPromise","myId","getForumTopic","setProperty","getPeerColorById","forum","avatarAvailable","avatarRendered","appAvatarsManager","isAvatarCached","first_name","last_name","getPeerInitials","returnDiv","setButtonLoader","RadioField","alignRight","RadioForm","radios","form","RangeSelector","events","setFilled","filled","stepStr","decimals","_removeListeners","addProgress","rectMax","offsetAxisValue","rippleClickId","attachListenerTo","handler","drawRipple","clickId","_handler","touchStartFired","clickY","isRippleUnneeded","touchEnd","setContent","Row","checkboxFieldOptions","radioField","noWrap","subtitleRight","subtitleRow","createRow","subtitleLangArgs","isToggle","withCheckboxSubtitle","titleRightContent","titleRightSecondary","titleRow","createTitle","navigationTab","buttonRightLangKey","_subtitle","createSubtitle","midtitle","_midtitle","createMidtitle","createMedia","disableWithPromise","makeSortable","sortIcon","toggleSorting","CreateRowFromCheckboxField","RadioFormFromRows","RadioFormFromValues","checkedRadioField","ScrollableBase","logPrefix","onScrollMeasure","lastScrollPosition","lastScrollDirection","isHeavyAnimationInProgress","needCheckAfterAnimation","cancelMeasure","onScrolledTop","scrollPosition","scrollProperty","addScrollListener","addedScrollListener","removeScrollListener","removeHeavyAnimationListener","Scrollable","onScrollOffset","withPaddingContainer","maxScrollTop","isScrolledDown","getDistanceToEnd","setScrollTopSilently","ignoreNextScrollEvent","ScrollableX","splitCount","scrollHorizontally","deltaX","scrollWidth","SettingSection","fakeGradientDelimiter","hr","generateContentElement","nameArgs","captionOld","captionArgs","generateSection","AppNewGroupTab","isGeoChat","setTitle","inputWrapper","groupNameInputField","groupLocationInputField","valueCheck","userLocationCoords","userLocationAddress","createChannel","geo_point","megagroup","inputFile","editPhoto","inviteToChannel","createChat","chatsSection","new","startLocating","geolocation","getCurrentPosition","lat","coords","latitude","long","longitude","uri","json","display_name","GeolocationPositionError","PrivacyType","getPrivacyRulesDetails","rules","types","allowPeers","users","chats","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","getSelf","captionEl","mePath","phoneSection","sCaption","AppTwoStepVerificationSetTab","stickerContainer","inputContent","btnReturn","sliceTabsUntilTab","AppSettingsTab","canFocus","isFirstInput","AppTwoStepVerificationEmailConfirmationTab","isFirst","email","codeInputField","passwordManager","confirmPasswordEmail","goNext","btnChange","btnResend","cancelPasswordEmail","AppTwoStepVerificationEmailTab","resendPasswordEmail","onOpenAfterTimeout","onContinueClick","btnContinue","btnSkip","matchEmail","toggleButtons","updateSettings","currentPassword","plainPassword","newPassword","symbols","AppTwoStepVerificationHintTab","onSkipClick","saveHint","AppTwoStepVerificationReEnterPasswordTab","monkey","verifyInput","AppTwoStepVerificationEnterPasswordTab","isNew","has_password","textEl","getStateInterval","getState","_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","invokeApi","otherSection","onError","onTerminateClick","menuElement","AppBlockedUsersTab","btnAdd","toggleBlock","bot","blocked","getBlocked","convertKeyToInputKey","toUpperCase","AppPrivacyVoicesTab","AppActiveWebSessionsTab","sessions","bot_id","region","domain","browser","appSeamlessLoginManager","resetWebAuthorizations","leftLength","resetWebAuthorization","AppPrivacyAndSecurityTab","fromTab","getAppConfig","globalPrivacy","getGlobalPrivacySettings","contentSettings","webAuthorizations","getWebAuthorizations","SUBTITLE","blockedPeerIds","blockedUsersRow","passwordState","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","appPaymentsManager","clearSavedInfo","deleteButton","appDraftsManager","clearAllDrafts","auths","AppQuickReactionTab","appReactionsManager","getQuickReaction","getAvailableReactions","quickReaction","availableReactions","reaction","inactive","availableReaction","static_icon","setDefaultReaction","emoticon","RangeSettingSelector","initialValue","minValue","writeValue","nameDiv","valueDiv","valueContainer","AppGeneralSettingsTab","themes","allStickers","chatBackgroundButton","initArgs","animationsCheckboxField","themesContainer","themesMap","currentTheme","themeController","isNight","applyThemeOnItem","theme","wallPaperContainer","wallPaperContainers","lastOnFrameNo","lastActive","restart","onFrameNo","frameNo","maxFrame","availableBaseThemes","defaultThemes","default","themeSettings","base_theme","wallPaper","wallpaper","emoticonContainer","bubbleIn","marginTop","dayRow","nightRow","systemRow","newIsNight","enterRow","ctrlEnterRow","kilometersRow","milesRow","formats","format","runFirst","getNextTimeout","_callback","run","eachTimeout","getSeconds","eachMinute","toLocaleTimeString","hour","minute","suggestCheckboxField","bigCheckboxField","reactionsRow","renderQuickReaction","getCustomEmojiDocument","document_id","loopCheckboxField","stickerSets","stickersContent","assumeType","AppChatFoldersTab","filtersRendered","animationData","lottieLoader","renderFolder","dialogFilter","non_contacts","broadcasts","bots","folder","getFolderDialogs","channels","isAnyGroup","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","langPack","autoDownloadPeerTypeSection","contactsCheckboxField","privateCheckboxField","groupsCheckboxField","channelsCheckboxField","AppAutoDownloadPhotoTab","AppAutoDownloadFileTab","debouncedSave","sizeMax","appStateManager","setByKey","MIN","MAX_RANGE","MAX","upTo","formatBytes","compareAndUpdate","AppAutoDownloadVideoTab","AUTO_DOWNLOAD_FOR_KEYS","private","AppDataAndStorageTab","autoCheckboxField","autoDownloadNew","autoRow","resetButton","deepEqual","setSubtitles","setAutoDownloadSubtitle","photoRow","videoRow","fileRow","file_size_max","openTab","tabConstructor","onDisabledChange","peerKeys","enabledKeys","isAll","logOut","edit","profile","fillPromise","changeAvatarBtn","upload","uploadProfilePhoto","updateChangeAvatarBtn","languageArgs","devicesRow","languageRow","buttonsSection","getEditProfileArgs","editProfileArgs","getAuthorizations","overwrite","getAuthorizationsPromise","AppNewChannelTab","channelNameInputField","channelDescriptionInputField","onLengthChange","broadcast","channelId","PopupCreateContact","importContact","nameInputField","lastNameInputField","telInputField","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","formatNumber","checkUpdateInterval","cache","status","ok","hasUpdate","onResize","documentElement","searchContainer","pickedElements","selectedPeerId","selectedMinDate","selectedMaxDate","updatePicked","removeProperty","helper","unselectEntity","renderEntity","dates","dateData","pushRecentSearch","peopleContainer","hideNewBtnMenuTimeout","transition","activeClassName","onFocus","clearRecentSearchBtn","clearRecentSearch","appSidebarLeft","AppAddMembersTab","attachToPromise","isPrivacy","removeLoader","averageColorFromCanvas","pixel","getImageData","pixelsLength","outPixel","Uint8ClampedArray","highlightningColor","rgba","l","ColorPicker","hue","saturation","lightness","onGrabStart","boxDragger","onGrabEnd","sliders","hueDragger","hexInputField","rgbInputField","inputs","valid","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","backgroundColor","throttle","isColored","AppBackgroundTab","clicked","wallPapersByElement","elementsByKey","onUploadClick","accept","requestFile","endsWith","createObjectURL","mimeType","scaleMediaElement","File","prepareWallPaperUpload","uploadPromise","uploadWallPaper","uploadDeferred","newKey","getWallPaperKey","setBackgroundDocument","addWallPaper","onResetClick","defaultTheme","blurCheckboxField","onGridClick","getWallPaperKeyFromTheme","backgrounds","uploadButton","colorButton","pattern","wallPapers","gridContainer","hasFile","isDark","dark","intensity","webkitMaskImage","_tempId","saveToCache","slug","hadSettings","onReady","getPixelPromise","imageUrl","imageSource","ratio","averageColorFromImageSource","averageColor","toDataURL","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","flag","hasOwnProperty","AppEditFolderTab","deleting","deleteFolderButton","updateDialogFilter","bool","menuBtn","inputSection","generateList","h2Text","to","includedFlagsContainer","excludedFlagsContainer","include","include_peers","editCheckForChange","reloadMissingPromises","reloadMissingPeerIds","onEditOpen","onCreateOpen","ignoreClick","hasPeer","getDialogOnly","filtered","filterAsync","renderMore","_length","exclude_peers","purchaseUsernameCaption","purchaseText","setUsername","AppEditProfileTab","bioMaxLength","userFull","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","animationPromise","appSidebarRight","AppEditContactTab","privacy","notificationsCheckboxField","profileNameDiv","profileSubtitleDiv","phoneRow","privacyRule","sharePhoneCheckboxField","btnDelete","deleteContacts","addContact","mediaSize","AppEditTopicTab","colorIndex","isGeneral","originalTopic","iconDiv","icon_emoji_id","setIcon","editForumTopic","topicId","iconEmojiId","createForumTopic","iconColor","onDestroy","emojiElement","icon_color","force","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","rights","banned_rights","editBanned","btnDeleteException","clearChannelParticipantBannedRights","kickFromChannel","exceptionText","toggleWith","defaultBannedRights","default_banned_rights","defaultRights","combineParticipantBannedRights","restrictionText","mainFlag","until_date","AppGroupPermissionsTab","chatPermissions","editChatDefaultBannedRights","addExceptionRow","openPermissions","getChannelParticipant","setSubtitle","bannedRights","cantWhat","getPeerId","setLength","exceptionsCount","loader","setLoader","getPromise","migrateFrom","migrateTo","AppChatReactionsTab","getActiveAvailableReactions","_chatReactions","available_reactions","chatReactions","reactions","makeReactionFromEmoticons","getCaptionLangPackKey","toggleSection","reactionsSection","toggleCheckboxFieldsByEmoticons","checkboxFieldsByEmoticon","toggleCheckboxField","toggleRow","save","checkboxFields","every","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","closeBtn","animatedCloseIcon","transitionContainer","transitionFirstItem","titleI18n","editBtn","transitionLastItem","secondTitle","setIsSharedMedia","isSharedMedia","isHeavy","onCloseBtnClick","toggleEditBtn","renderNewMessage","msgs","deleteDeletedMessages","btnAddMembers","showConfirmation","addChatUser","_renderNewMessage","getMessageThreadId","_deleteDeletedMessages","setLoadMutex","peerChanged","changeTitleKey","loadSidebarMedia","destroyable","SetTransition","raf","afterTimeout","SidebarSlider","closeTab","closingId","getMiddleware","onOpenTab","preserveTab","getTab","getHistory","isTabExists","deleteTab","doNotAppend","SliderSuperTab","_constructor","SliderSuperTabEventable","dispatchResultableEvent","SortedUserList","getIndex","getUserStatusForSort","onDelete","listEl","onListLengthChange","onUpdate","willChangeLength","onElementCreate","base","updateElementWith","updateListWith","createChatListOptions","doTimeout","updateList","SORT_INTERVAL","hasViewer","attachStickerViewerListeners","findTarget","originalFindTarget","checkForParent","closest","mediaContainer","previousGroup","_middleware","previousTransformer","doThatSticker","lockGroups","isSwitching","effectThumb","mediaRect","boxSize","fitted","aspectFitted","transformer","transformX","transformY","needFadeIn","withThumb","relativeEffect","loopEffect","firstFramePromise","prevPlayer","ready","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","shiftKey","onWheelZoom","handleWheelDrag","isDragCanceled","sign","initialDragOffset","dx","dy","delta","wheelZoom","listenerOptions","setCursor","onSwipeResult","TelInputField","pasted","lastValue","telEl","HTMLInputElement","pixelRatio","letterSpacing","IS_ANDROID","originalFunc","formattedPhoneNumber","leftPattern","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","CLASS_NAME","_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","audioElement","extSplitted","ext","docDiv","icoDiv","icoTextEl","hadContext","hasThumb","performance","fileName","bytesContainer","descriptionParts","bytesMaxEl","sizeDiv","_downloadDiv","addByteProgress","sizeContainer","_bytesContainer","_d","canOpenAfter","downloadFileName","downloadId","apiFileManager","isDownloading","support","was_online","today","getDate","dateEl","timeEl","toggleMediaSpoiler","reveal","destroyAfter","onMediaSpoilerClick","wrapMediaSpoiler","wrapMediaSpoilerWithImage","wrapMessageActionTextNew","plain","hadColors","wrapJoinVoiceChatAnchor","wrapUrl","wrapLinkToMessage","savedFrom","dir","wrapSomeText","htmlToSpan","wrapTopicIcon","ns","contentSpan","gradientId","strokeColor","clone","topicAvatar","wrapMessageActionTopicIcon","wrapMessageActionTopicIconAndName","wrapMessageActionTextNewUnsafe","unsafeMessage","getNameDivHTML","formatCallDuration","post","schedule_date","daysToStart","tomorrowDate","_args","day","pinnedMessage","reply_to_mid","fetchMessageReplyTo","user_id","joined","anchorHTML","isRecurringInit","recurring_init","isRecurringUsed","recurring_used","paymentsWrapCurrencyAmount","total_amount","currency","invoiceMessage","reply_to","reply_to_peer_id","period","titleElement","authorElement","isMe","isIconChanged","isIconRemoved","isTitleChanged","isHiddenChanged","closed","waited","wrapMessageForReply","usingMids","withoutMediaType","hasAlbumKey","addPart","part","isRestricted","usingFullAlbum","grouped_id","getMidsByMessage","albumText","getAlbumText","poll","question","game","extended_media","actionWrapped","restriction_reason","exec","messageWrapped","noLinks","noTextFormat","wrapPeerTitle","wrapPhoto","withTail","noThumb","blurAfter","isImageFromDocument","startsWith","isWebDoc","isFit","renderOnLoad","canAttachPreloader","haveToDownload","onlyCache","getDownloadPromise","wrapSenderToPeer","senderTitle","fromMe","wrapSentTime","STICKER_EFFECT_MULTIPLIER","locksUrls","videosCache","_timeout","wrapSticker","loadStickerMiddleware","exportLoad","needUpscale","skipRatio","asStatic","fullThumb","noPremium","isCustomEmoji","syncedVideo","stickerType","emojiSticker","animatedSticker","staticSticker","isAnimated","getStickerEffectThumb","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","animationDiv","stickerPromise","side","attachStickerEffectHandler","onEmojiStickerClick","getAnimatedEmojiSoundDocument","getAnimatedEmojiSticker","emojiData","sendInteractionThrottled","msg_id","interaction","JSON","stringify","withRandomOffset","wrapStickerAnimation","unmountAnimation","vibrate","generateRandomSigned","randomOffsetX","randomOffsetY","setPosition","factor","stableOffsetX","stableOffsetY","rectX","rectY","addOffsetX","addOffsetY","wrapStickerEmoji","wrapStickerSetThumb","downloadOptions","getStickerSetThumbDownloadOptions","videos","getDocPromise","thumb_document_id","wrapStickerToRow","previousMedia","_size","wrapTopicNameButton","roundVideoCircumference","wrapVideo","videoSize","noAutoplayAttribute","isAlbumItem","canAutoplay","spanTime","spanPlay","needPlayButton","photoRes","divRound","halfSize","strokeDashoffset","globalVideo","onPaused","onFrame","renderDeferred","loadPhotoThumbFunc","wrapWebPageDescription","shortDescriptionText","wrapWebPageTitle","shortTitle","site_name","EmojiVersions","Emoji","version","FontFamily","FontSize","FontWeight","instances","getAnimationInstance","cancelAnimationByKey","instance","isCancelled","animateSingle","tick","createAnimationInstance","array","AudioAssetPlayer","assets","playSound","assetName","createAudio","playSoundIfDifferent","Audio","stopSound","cancelDelayedPlay","playSoundWithTimeout","heavyQueue","processingQueue","addHeavyTask","processHeavyQueue","todo","possiblePromise","process","realResult","timedChunk","requireBlurPromise","fastBlurFunc","processBlurNext","dataUri","JPEG_HEADER","bytesFromHex","JPEG_TAIL","getPreviewBytesFromURL","needle","jpegBytes","atob","char","charCodeAt","isSticker","convertToUint8Array","dataURL","btoa","bytesToDataURL","calcImageInBox","imageW","imageH","boxW","boxH","noZoom","boxedImageW","boxedImageH","drawCircle","beginPath","closePath","drawCircleFromStart","getTextWidth","measureText","source","createImageBitmap","resizeWidth","resizeHeight","quality","badCharsRe","trimRe","C2L","clearBadCharsAndTrim","latinize","processSearchText","clearBadChars","ignoreCase","hasTag","includeTag","charAt","originalText","ch","latinizeCh","latinizeString","fixCyrillic","fallbackCopyTextToClipboard","textArea","removeChild","copyTextToClipboard","clipboard","writeText","ContextMenuController","diffX","diffY","isOpened","openBtnMenu","months","days","ONE_DAY","getWeekNumber","UTC","getMonth","dayNum","getUTCDay","setUTCDate","getUTCDate","yearStart","getUTCFullYear","formatDateAccordingToTodayNew","weekday","formatFullSentTimeRaw","formatTime","capitalize","textTransform","formatFullSentTime","getFullDate","joiner","monthAsNumber","getHours","getMinutes","noSeconds","leadingZero","noTime","minYear","yearPattern","monthYearOrDayPattern","yearOrDayAndMonthPattern","shortDate","longDate","numberOfDaysEachMonth","fillTipDates","setFullYear","dayOfWeek","formatWeekLong","getDay","getDayOfWeek","setTime","g1","g2","createForDayMonth","createForMonthYear","selectedYear","currentYear","g3","validDateForMonth","formatterYearMax","k1","setMonth","formatterMonthYear","formatterDayMonth","T_ME","copyWhat","copyText","_cancelContextMenuOpening","_cancelContextMenuOpeningTimeout","cancelContextMenuOpening","onCancel","onMove","isTouch","onTouchEnd","touch","changedTouches","CLICK_EVENT_NAME","touchMouseDown","detachClickEvent","simulateClickEvent","ControlsHover","setHideTimeout","hideControlsTimeout","isShown","controlsLocked","toggleControls","relatedTarget","createContextMenu","findElement","filterButtons","onBeforeOpen","initResult","verifyFavoriteSticker","toAdd","favedStickers","_doc","disablePictureInPicture","resetCache","computedStyle","getProperty","getPropertyAsSize","simulateEvent","childNodes","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","field","withEntities","withCaret","DocumentFragment","startOffset","startContainer","possibleChildrenFocusOffset","getCaretPos","caretPos","getViewportSlice","overflowRect","extraSize","invisibleTop","invisibleBottom","foundVisible","lookForSticky","overflowTop","overflowRight","overflowBottom","overflowLeft","sticky","windowWidth","windowHeight","handleHorizontalSwipe","cancelY","template","isSendShortcutPressed","isComposing","secondaryKey","isSwipingBackSafari","TouchEvent","placeCaretAtEnd","ignoreTouchCheck","selectionStart","selectionEnd","prevPos","backgroundImage","useCache","isImage","renderImageFromUrlPromise","renderMediaWithFadeIn","compareNodes","node1","node1Offset","node2","node2Offset","parents","commonAncestorContainer","NOT_ONLY_BOMS_REG_EXP","USING_BOMS","RichInputHandler","saveSelectionOnChange","saveRangeForElement","onFocusOut","lastNode","lastOffset","onSelectionChange","setSelectionClassName","caret","getCaretPosN","move","superMove","modify","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","makeFocused","newCallback","sibling","needed","treeWalker","createTreeWalker","NodeFilter","SHOW_TEXT","acceptNode","FILTER_REJECT","FILTER_ACCEPT","textNode","nextNode","removePossibleBOMSiblings","removePossibleBOMSiblingsByNode","cleanSiblings","insertData","bomNode","intersectsNode","focusNode","focusNodeBefore","focusOffset","focusOffsetBefore","collapseToStart","collapseToEnd","focusNodeAfter","focusOffsetAfter","prepareApplyingMarkdown","fillers","smths","INSTANCE","Sortable","elementRect","lastSiblings","siblings","property","getSortableTarget","scrollableRect","toEnd","addScrollPos","scrollPos","startScrollPos","isVertical","countNonElements","DropdownHover","onClickOut","ignoreButtons","ignoreMouseOut","toElement","willBeActive","inited","timeouts","attachButtonListener","setIgnoreMouseOut","onmouseout","onmouseover","FocusDirection","fastSmoothScroll","maxDistance","Static","scrollWithJs","getNormalSize","rectStartKey","rectEndKey","sizeKey","scrollSizeKey","elementScrollSizeKey","scrollPositionKey","possibleElementPosition","containerSize","scrollSize","fallbackToElementStartWhenCentering","remainingPath","absPath","startAt","shortTransition","longTransition","currentPath","distanceToEnd","FILENAME_JOINER","getFileNameByLocation","thumb_size","big","stickerset","short_name","thumb_version","volume_id","local_id","strictDecimals","_decimals","dm","fixed","pow","parseFloat","CALL_DURATION_LANG_KEYS","mm","showLast","dd","formatDuration","strings","prefixes","maxPrefixLength","setPrefix","originalStr","prefixCountry","patterns","searchForPattern","mostMatchedPatternMatches","mostMatchedPattern","_pattern","patternMatches","symbol","FramesCache","framesNew","framesURLs","getCache","createCache","releaseCache","getCacheCounter","generateName","arcParameter","rx","ry","xAxisRotation","largeArcFlag","sweepFlag","tl","tr","bl","useBlur","ignoreCache","ListLoader","loadedAllDown","setLoaded","unsetCurrent","toPrevious","goUnsafe","down","loadPromiseDown","loadPromiseUp","processedArr","processed","ListenerSetter","listeners","addManual","onceCallback","onceFired","_listener","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","invoice","extendedInvoice","customEmoji","esgCustomEmoji","popupSticker","desktop","isMobile","handleResize","innerWidth","activeScreen","wasScreen","rAF","throwWhat","numberThousandSplitter","HAVE_METADATA","useCanplayOnIos","loadEventName","errorEventName","OverlayClickHandler","withOverlay","amount","skipSymbol","isNegative","currencyData","amountExp","exp","number","dec_point","thousands_sep","isFinite","prec","sep","dec","toFixedFix","number_format","decimal_sep","space_between","symbol_left","splitter","additionalPadding","getScrollWidthFromElement","menuWidth","menuHeight","paddingRight","paddingBottom","paddingLeft","verticalSide","maxTop","maxLeft","minLeft","sides","intermediateX","intermediateY","possibleSides","platforms","getRestrictionReason","reasons","reason","savingLottiePreview","isSavingLottiePreview","saving","throttleWithRaf","fn","schedulerFn","waiting","throttleWith","ScrollableLoader","SearchListLoader","messageId","generateMessageId","filterMids","onHistoryDelete","shouldBeDeleted","onHistoryMultiappend","onMessageSent","isInner","otherSideLoader","filterMessagesByInputFilterFromStorage","goToOtherEnd","do","kind","scheduleFlush","measure","mutate","mutateElement","read","write","pushDocumentSize","_isWebDocument","replies","comments","channel_id","BatchProcessor","bindPrefix","queuePromise","addToQueue","setQueue","possibleError","perf","renderedQueue","SortedList","batchProcessor","_updateList","canUpdate","createPromise","noScheduler","encodeEntities","limitFrom","leadZero","sec_num","hours","minutes","seconds","textToSvgURL","Blob","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","onPinClick","toggleDialogPin","onUnmuteClick","onUnreadClick","unread_count","readHistory","top_message","markDialogUnread","getButtons","getDialogOrTopic","getDeleteButtonText","lastButton","isDialogUnread","pinned","ConnectionStatusComponent","hadConnect","connecting","timedOut","updating","setConnectionStatus","overrideStatus","baseDcId","connectionStatus","setFirstConnectionTimeout","online","apiUpdatesManager","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","totalHeight","lineHeight","lineBorderRadius","lineMarginVertical","statusWidth","getRectFrom","onRemove","blockScrollable","overflowY","availableLength","detachTime","renderDetachAnimationFrame","globalCompositeOperation","completed","elapsedRowTime","dialogHeight","renderFrame","createPattern","patternCanvas","patternContext","drawChat","firstLineWidth","secondLineWidth","marginLeft","shake","keyframes","setPromiseMiddleware","oldPromise","SortedDialogList","getDialogIndex","forumPeerId","indexKey","addListDialog","isBatch","isMainList","DialogElement","bigger","abitbigger","small","captionDiv","titleSpanContainer","peerTitlePromise","statusSpan","lastTimeSpan","rightSpan","dialogDom","setDialogActive","forumTab","createUnreadBadge","unreadBadge","badge","createUnreadAvatarBadge","unreadAvatarBadge","createMentionsBadge","mentionsBadge","toggleBadgeByKey","hasBadge","justCreated","ForumTab","init2","isFloating","toggleForumTab","createChatList","setListClickListener","xd","Some3","bindScrollable","getOptionsForMessages","fullReset","subscribeToChannelUpdates","unsubscribeFromChannelUpdates","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","dialogSize","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","unread","unreadUnmutedCount","unreadCount","getFolderUnreadCount","wasShowing","generateEmptyPlaceholder","classNameType","subtitleArgs","placeholderContainer","needPlaceholder","emptyDialogsPlaceholderSubtitle","usersLength","placeholderType","updatePartClassName","updateContactsLengthPromise","newTab","hideTab","forumNavigationItem","toggleForumTabByPeerId","lastTab","isSameTab","withContext","openInner","lastActiveListElement","setPeerFunc","setLastMessage","draftMessage","draft","topMessage","isSearch","isMessageRestricted","willPrepend","videoTypes","playIcon","replyTo","forum_topic","setUnreadMessages","isDialogPinned","getForumUnreadCount","hasUnmuted","isPinned","forumUnreadCount","wasMuted","unreadTopicsCount","hasUnmutedTopic","setStatusMessage","read_inbox_max_id","hasUnreadBadge","hasUnreadAvatarBadge","transitionDuration","disableAnimationIfRippleFound","iconClassName","setSendingStatus","isUnreadBadgeMounted","hasMentionsBadge","unread_mentions_count","isMentionsBadgeMounted","isBadgeMounted","unreadBadgeText","isUnread","isMention","notVisited","getDialog","originalDialog","getOutputPeer","addDialogNew","addDialogAndSetLastMessage","getMessageSenderPeerIdOrName","downloads","getNewDeferred","cancelDownload","clearDownload","getNewDeferredForUpload","getUpload","getDownload","getUploadPromise","getDownloadFileNameFromOptions","downloadMedia","promiseBefore","getDownloadMediaDetails","downloadMediaURL","downloadMediaVoid","getFileNameForUpload","downloadToDisc","justAttach","pingPromise","iframe","hadProgress","getDocumentDownloadOptions","getPhotoDownloadOptions","clickEvent","createEvent","initMouseEvent","createDownloadAnchor","revokeObjectURL","partition","bad","BubbleGroup","avatarLoadPromise","avatarContainer","fwdFrom","fwdFromId","isForwardFromChannel","from_id","currentPeerId","firstTimestamp","firstItem","firstMid","lastTimestamp","lastItem","lastMid","updateClassNames","insertItem","insertInDescendSortedArray","sortGroupItemsKey","insertGroup","mount","onItemUnmount","mountItem","onItemMount","unmountItem","dateContainer","getDateContainerByTimestamp","dateGroups","_group","dateGroupsLength","unmountedLength","STICKY_OFFSET","deleteEmptyDateGroups","BubbleGroups","itemsArr","itemsMap","newGroupDiff","sortItemsKey","sortGroupsKey","removeItemFromCache","removeAndUnmountBubble","getItemByBubble","getSiblingsAtIndex","modifiedGroups","canItemsBeGrouped","groupUngrouped","mountUnmountGroups","toMount","toUnmount","getLastGroup","changeBubbleMid","insertItemToArray","changeItemBubble","changeBubbleByBubble","item1","item2","isAllMessagesForum","itemIndex","findGroupSiblingByItem","findGroupSiblingInItems","previousItem","siblingGroupedItem","nextItem","addItemToGroup","addItemToCache","getMessageFromId","createItem","SERVICE_AS_REGULAR","getDateForDateContainer","groupMid","splitSiblingsOnGrouping","prepareForGrouping","hadGroup","foundItem","splittedGroups","PopupDatePicker","initDate","onPick","noButtons","selectedDate","selectedMonth","minMonth","prevBtn","maxMonth","onDateClick","selectedEl","setTimeTitle","controlsDiv","monthTitle","monthsContainer","handleTimeInput","onOverflow","maxString","hoursInputField","minutesInputField","setMinutes","popupCenterer","timeOptions","sendDate","dateOptions","renderElement","firstDate","weekStartDate","dayIndex","clonedDate","showOverflowMonths","remainder","DivAndCaption","MEDIA_SIZE","wrapReplyDivAndCaption","mediaEl","messageMedia","isRound","mediaChildren","video_thumbs","ReplyContainer","isMediaSet","wrapReply","setColorPeerId","replyContainer","AVATAR_CLASS_NAME","AVATAR_CONTAINER_CLASS_NAME","StackedAvatars","TAG_NAME","RepliesElement","updated","postKey","leftPart","recent_repliers","stackedAvatars","read_max_id","max_id","textSpan","iconSpan","rippleContainer","subscribeRepliesThread","updateMessage","makeEdited","edited","makeSponsored","MessageRender","chatType","editedSpan","sponsoredSpan","isSponsored","sponsored","isMessage","views","postAuthor","post_author","postViewsSpan","channelViews","edit_date","edit_hide","timeSpan","clonedArgs","renderReplies","bubbleContainer","messageDiv","isFooter","repliesFooter","setReply","isReplacing","currentReplyDiv","replyToPeerId","originalMessage","originalPeerTitle","titlePeerId","originalMessageFwdFromId","needUpdate","replyMid","reflowScrollableElement","SEND_WHEN_ONLINE_TIMESTAMP","INTERNAL_LINK_TYPE","PopupJoinChatInvite","chatInvite","request_needed","importChatInvite","savePhoto","peopleCount","ReactionElement","reactionCount","_reactionCount","setCanRenderAvatars","canRenderAvatars","doNotRenderSticker","hadStickerContainer","getReaction","callbackify","center_icon","renderDoc","wrapPromise","wrapStickerPromise","renderCounter","displayOn","renderAvatars","recentReactions","peer_id","setIsChosen","isChosen","chosen_order","fireAroundAnimation","REACTION_INLINE_SIZE","REACTION_BLOCK_SIZE","around_animation","iconPlayer","aroundPlayer","removeOnFrame","REACTIONS_ELEMENTS","ReactionsElement","middlewareHelpers","onConnectCallback","getReactionCount","reactionElement","getMessage","isPlaceholder","changeMessage","changedResults","hasReactions","counts","reactionsEqual","totalReactions","can_see_list","recent_reactions","handleChangedResults","ScrollSaver","getSaved","findElements","replaceSaved","findAndSetElements","_save","scrollHeightMinusTop","onRestore","useReflow","setScrollTop","newScrollTop","restore","_restore","previousScrollHeightMinusTop","SuperIntersectionObserver","observing","observingQueue","freezedObservingNew","toggleObservingNew","isMentionUnread","mentioned","accumulate","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","buggedRegExp","getDistanceFromBuggedToNormal","fixBuggedNumbers","makeOptionalCharacter","consumed","makeRequiredCharacter","partial","wrapCharacterRegExpFactory","optional","_regExp","makeCharacter","makeMonthDigitPatternCharacter","digit","capitalCharacter","cleanedResult","formattingCharacter","str1","makeFormattingCharacter","optionalPattern","spaceCharacter","yearOptionalPattern","sixteenPattern","fifteenPattern","requiredPostcodes","generateFourPattern","cardFormattingPatterns","cardNumber","cardExpiry","cardCvc","cardCvcFromBrand","postalCodeFromCountry","optionalDigits","accumulateLengths","strs","nbspRegExp","makeValidationError","validateCardNumber","sanitized","getCardInfoByNumber","ignoreIncomplete","validateCompleteCardNumber","makeCardNumberError","validateCardExpiry","monthStr","yearStr","_year","nextMonth","isNaN","validateExpiry","parse","TelegramWebView","sandbox","onTelegramWebViewEvent","eventType","eventData","onMount","contentWindow","createVerificationIframe","allow","PopupPaymentVerification","openPathAfter","telegramWebView","path_full","InputFieldCorrected","lastKeyDown","lastTransformed","getPattern","pushRest","autocorrectComplete","character","getCharacter","meta","formatInputValueByPattern","formatMethod","transformedValue","validateNew","onBlur","justReturn","validateMethod","validateAnyIncomplete","errorKeys","handleInputFieldsOnChange","_onChange","createCountryZipFields","zip","countryInputField","postcodeInputField","SUPPORTED_NATIVE_PROVIDERS","PopupPaymentCard","paymentForm","savedCard","native_provider","cardOut","token","credentials","can_save_credentials","cardSection","nativeParams","native_params","lastBrand","lastBrandImg","brandIconTempId","cardInputField","invalid","incomplete","transformed","getPaymentBrandIconPath","setBrandIcon","cvcInputField","need_cardholder_name","expireInputField","switchFocusOrder","previousInputField","nextInputField","inputFieldsRow","billingSection","need_country","need_zip","canSave","saveCheckboxField","saveRow","payButton","PaymentButton","expiryFull","expiryMonth","expiryYear","cvc","cardholderName","nativeProvider","URLSearchParams","headers","publishable_key","expiration_month","expiration_year","security_code","public_token","PopupPaymentCardConfirmation","inputCheckPassword","getInputCheckPassword","tmpPassword","password","handled","PopupPaymentShipping","inputInvoice","savedInfo","saved_info","addressSection","address1InputField","address2InputField","cityInputField","stateInputField","receiverSection","emailInputField","shipping_address_requested","name_requested","email_requested","phone_requested","validateEmail","validatePhone","selectedCountry","shipping_address","street_line1","street_line2","city","country_iso2","post_code","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","lastShippingId","option","PopupPayment","isReceipt","tipButtonsMap","confirmed","onConfirmed","popupPaymentVerification","mediaInvoice","receipt_msg_id","isTest","itemEl","detailsClassName","photoEl","linesClassName","linesEl","botName","preloaderContainer","getPaymentReceipt","getPaymentForm","savedCredentials","saved_credentials","lastRequestedInfo","providerPeerTitle","provider_id","wrapAmount","isRecurring","recurring","peerTitle2","makeLabel","pricesClassName","makePricesElements","price","_label","wrappedAmount","pricesElements","getTipsAmount","shippingAmount","setTotal","totalAmount","totalLabel","payI18n","canTip","max_tip_amount","tip_amount","tipsClassName","getInputValue","setInputWidth","setInputValue","unsetActiveTip","tipEl","tipsLabel","haveToIgnoreEvents","ignoreNextSelectionChange","tipsEl","tipClassName","tipButtons","suggested_tip_amounts","tipAmount","prevTipEl","setRowIcon","setRowTitle","setCardSubtitle","methodRow","onMethodClick","previousCardDetails","previousToken","credentials_title","providerRow","providerAvatar","shippingAddressRow","shippingNameRow","shippingEmailRow","shippingPhoneRow","shippingMethodRow","lastShippingOption","onShippingAddressClick","onShippingMethodClick","setShippingTitle","postAddress","setShippingInfo","setShippingOption","scrollSaver","lastShippingPricesElements","shipping","acceptTermsCheckboxField","recurring_terms_url","acceptTermsRow","recurringElements","lastTmpPasword","missingInfo","tmp_password","paymentResult","sendPaymentForm","form_id","_passwordState","valid_until","tsNow","Layouter","minWidth","spacing","ratios","countRatios","proportions","countProportions","averageRatio","maxSizeRatio","layout","ComplexLayouter","layoutTwo","layoutThree","layoutFour","layoutTwoTopBottom","layoutTwoLeftRightEqual","layoutTwoLeftRight","layoutThreeLeftAndOther","layoutThreeTopAndOther","layoutFourTopAndOther","layoutFourLeftAndOther","geometry","RectPart","minimalWidth","secondWidth","firstWidth","firstHeight","thirdHeight","secondHeight","rightWidth","leftWidth","thirdWidth","h0","w0","w2","w1","h1","h2","cropRatios","attempts","multiHeight","sum","pushAttempt","lineCounts","heights","second","third","fourth","optimalAttempt","optimalDiff","attempt","lineCount","minLineHeight","bad1","bad2","optimalCounts","optimalHeights","rowCount","colCount","col","prepareAlbum","widthItem","heightItem","borderTopLeftRadius","borderBottomLeftRadius","borderTopRightRadius","borderBottomRightRadius","forMedia","mediaDiv","wrapAlbum","attachmentDiv","uploading","containerHeight","hasSpoiler","itemWidth","itemHeight","AppPollResultsTab","resultsDiv","appPollsManager","getPoll","quiz","voters","total_voters","roundPercents","answer","answers","answerEl","answerTitle","answerPercents","getVotes","votesList","votes","vote","lineTotalLength","minIndex","minRemainder","maxRemainder","pollElement","isClosed","performResults","chosenIndexes","PollElement","setMaxLength","resizePolls","hideQuizHint","onHide","prevQuizHint","prevQuizHintOnHide","prevQuizHintTimeout","isListenerSet","isQuiz","isRetracted","isPublic","isMultiple","chosingIndexes","sentVote","MAX_LENGTH","MAX_OFFSET","svgLines","setLineProgress","descKey","public_voters","multiple_choice","multipleSelect","descDiv","typeDiv","avatarsDiv","close_period","close_date","timeLeftDiv","quizTimer","circumference","closeTime","quizInterval","timeLeft","getResults","answerDivs","numberDivs","footerDiv","viewResults","votersCountDiv","sendVoteBtn","sendVotes","canVote","setVotersCount","clickHandler","initQuizHint","solution","solution_entities","toggleHint","setQuizHint","correctResult","correct","chosen","answerIndex","foundIndex","indexes","sendVotePromise","sendVote","recent_voters","isVoted","hideSendVoteBtn","hideViewResultsBtn","maxPercents","getPercentValue","iterate","fullTime","votersCount","rtlChars","justRtlDirCheck","IGNORE_ACTIONS","TEST_SCROLL_TIMES","TEST_SCROLL","PEER_CHANGED_ERROR","BIG_EMOJI_SIZES","BIG_EMOJI_SIZES_LENGTH","getMainMidForGrouped","ChatBubbles","unreadOut","bubblesNewByGroupedId","bubblesNew","dateMessages","scrolledDown","isScrollingTimeout","unreaded","unreadedSeen","messagesQueueOnRenderAdditional","firstUnreadBubble","followStack","isFirstLoad","passEntities","viewsMids","isTopPaddingSet","renderingMessages","bubblesToEject","bubblesToReplace","setPeerTempId","renderNewPromises","extendedMediaMessages","unreadedObserverCallback","onUnreadedInViewport","viewsObserverCallback","sendViewCountersDebounced","sponsoredMessage","randomId","random_id","viewSponsoredMessage","stickerEffectObserverCallback","onBubblesMouseMove","unhoverPrevious","hoverBubble","hoverReaction","setHoverVisible","stickerWrapper","getGroupsFirstMessage","getAvailableReactionsByMessage","select_animation","sendReaction","onBubblesClick","setInnerPeer","chatInner","onDatePick","contactDiv","callDiv","callUser","getInputInvoiceByPeerId","reactionsElement","stickerEmojiEl","bubbleMid","reply_to_top_id","saved_from_msg_id","openThread","message1","getMessageWithReplies","getDiscussionMessage","via","setDraft","peerIdStr","documentDiv","groupedItem","SINGLE_MEDIA_CLASSNAME","isSingleMedia","hasAspecter","albumItem","isReplyClick","replyToMid","reply_to_msg_id","scrollDimensions","forceDown","sliceViewportDebounced","setCorrectIndexThrottled","setStickyDateManually","setPeerPromise","processBatch","loadQueue","filterQueue","avatarPromises","groupBubbles","updatePosition","timePromises","groupCollapsed","groupEnd","setUnreadDelimiter","restoreScroll","prepareToSaveScroll","ejectBubbles","oldBubble","bubbleGroups","updatePlaceholderPosition","requestHistory","setMessageId","constructBubbles","sequential","messagesStorageKey","messagesQueuePromise","newItem","_items","scrollingToBubble","scrollToEnd","deleteMessagesByIds","tempMessage","_bubble","groupedId","getMessagesByAlbum","reactionsElements","repliesElement","newDiv","safeRenderMessage","scrollToBubbleIfLast","deletedMids","wasMainMid","mainMid","createScrollSaver","appendReactionsElementToBubble","dateMessage","dateBubble","previousStickyDate","sliceViewport","setScroll","attachContainerListeners","highlightBubble","replyAfter","swipeAvatar","shouldReply","canSend","_target","_swipeAvatar","initMessageReply","constructPeerHelpers","updateGradient","setUnreadCount","updateUnreadByDialog","finishPeerChange","reloadMessages","toDelete","postViewsElements","different","postViews","incrementMessageViews","getScheduledMessagesStorage","createResizeObserver","resizeObserver","wasHeight","skip","scrolled","onResizeEnd","setEndRAF","ResizeObserver","contentRect","realDiff","_part","needScrollTop","destroyResizeObserver","setReactionsHoverListeners","getRenderedLength","readUnreaded","readPromise","idleController","bubblesMaxId","getHistoryMaxId","readContents","onGoDownClick","getBubbleByPoint","getGroupedBubble","groupId","getMidsByAlbum","findNextMountedBubbleByMsgId","filterCallback","_mid","foundMid","loadMoreHistory","getHistoryTopPromise","getHistoryBottomPromise","getHistory1","destroyScrollable","getHistoryStorage","readMaxId","readOutboxMaxId","msgId","destroyBubble","permanent","ignoreOnScroll","pollExtendedMediaMessages","getExtendedMedia","setExtendedMediaMessagesPollInterval","pollExtendedMediaMessagesPromise","setTopPadding","setPaddingTo","isPaddingNeeded","unsetPadding","newMessage","getLastBubble","performHistoryResult","scrollToBubbleEnd","scrollToBubble","isChangingHeight","messageInput","dimensions","datasetKey","createDateBubble","bubbleContent","serviceMsg","fakeBubble","bubblesToo","cleanupPlaceholders","attachedUnreadBubble","fetchNewPromise","getSponsoredMessagePromise","onAnimateLadder","resolveLadderAnimation","attachPlaceholderOnRender","emptyPlaceholderBubble","samePeer","stack","startParam","onChangePeer","getPinnedMessagesMaxId","isTarget","followingUnread","savedPosition","overrideAdditionMsgId","getChatSavedPosition","getReadMaxIdIfUnread","foundSlice","findSliceOffset","isJump","isStartButtonNeeded","setStartParam","setQueueId","messageEntityBotCommand","isBot","additionMsgId","maxBubbleId","oldChatInner","oldPlaceholderBubble","haveToScrollToBubble","fromUp","scrollFromDown","scrollFromUp","willScrollOnLoad","setPeerOptions","waitPromise","setPeerCached","mountedByLastMsgId","isPinnedMessagesNeeded","setCorrectIndex","lastBubble","onRenderScrollSet","afterSetPromise","setFetchReactionsInterval","setFetchHistoryInterval","onScrolledAllDown","isForumTopic","unread_mark","fetchReactions","getMessagesReactions","needFetchInterval","isFetchIntervalNeeded","historyMaxId","canWrite","renderMessagesQueue","isAvatarNeeded","additionalCallback","processResult","newBubble","originalPromise","renderMessage","albumMids","reactionsMessage","albumMessages","albumMustBeRenderedFull","our","isOurMessage","contentWrapper","isInUnread","ignoreAction","chat_id","is_single","messageMessage","needToSetHTML","bigEmojis","emojiEntities","strLength","curr","richText","canHaveTail","isStandaloneMedia","haveRTLChar","topicNameButtonContainer","replyMarkup","reply_markup","replyMarkupRows","containerDiv","rowDiv","buttonEl","botId","viaBotId","same_peer","checkSwitchReturn","switchInlineQuery","button_id","handleUrlAuth","buttonId","haveButtons","column","callbackButtonClick","callbackAnswer","messageWithReplies","getMessageWithCommentReplies","withReplies","isOutMessage","nameContainer","canHideNameIfMedia","isMessageEmpty","viewButton","processingWebPage","telegram_channel","telegram_megagroup","telegram_bot","makeViewButton","quote","previewResizer","preview","quoteTextDiv","strong","titleDiv","textDiv","isSquare","isEmoji","nopremium","newNameContainer","richTextFragment","getMidsByMid","wrapGroupedDocuments","lastContainer","addClassName","contact","contactDetails","contactNameDiv","fullName","contactNumberDiv","phone_number","wrapPoll","extendedMedia","isAlreadyPaid","isNotPaid","innerMedia","wrappedPrice","priceEl","video_duration","videoTime","dc_id","file_reference","before","needName","titleVia","mustHaveName","isHidden","isForward","goto","generateTail","documentContainer","documentMessageDiv","viewportSlice","deleteViewportSlice","historyResult","needReflowScroll","setLoadedPromises","firstSlice","lastSlice","both","processLocalMessageRender","ackedResult","getScheduledMessages","animateAsLadder","additionMsgIds","isAdditionRender","targetMid","sortedMids","topIds","middleIds","bottomIds","setBubbles","lastMsDelay","elementsToAnimate","transitionDelay","topRes","middleRes","bottomRes","delays","renderEmptyPlaceholder","listElements","getRestrictionReasonText","getGreetingSticker","channel_post","start_param","chat_invite","chat_invite_hash","JOIN_CHAT","invite","processInternalLink","creator","isWaitingForAnimation","noTransition","setOn","generateLocalMessageId","addOffset","generateLocalFirstMessage","service","saveMessages","ignoreScrollSaving","invisible","checkPlaceholders","toggleSponsoredMessage","renderBotPlaceholder","checkIfEmptyPlaceholderNeeded","getSponsoredMessage","sponsoredMessages","messagePromise","_log","getProfile","processPromise","bot_info","botInfo","description_document","description_photo","isBackLimit","resultPromise","isFirstMessageRender","serviceStartMessageId","getThreadServiceMessageId","sup","_promise","mustBeCount","PopupPinMessage","unpin","canUnpin","canPinMessage","oneSide","unpinAllMessages","hidePinnedMessages","updatePinnedMessage","buttonText","getPinnedMessagesCount","pinButtonText","isSelectionEmpty","selectionRange","START_TO_END","preloadAnimatedEmojiSticker","PopupReportMessagesConfirm","reportMessages","STICKER_EMOJI","PopupReportMessages","preloadStickerPromise","PopupSponsored","PopupReactedList","canViewReadParticipants","canViewMessageReadParticipants","loaders","hasAllReactions","createFakeReaction","hasReadParticipants","readUserIds","getMessageReadParticipants","chatlist","skipReadParticipants","skipReactionsList","getMessageReactionsListAndReadParticipants","combined","getReactionCached","allReactionsSticker","REACTIONS_CLASS_NAME","REACTION_CLASS_NAME","CAN_USE_TRANSFORM","ChatReactionsMenu","reactionsMap","players","onScrollProcessItem","reactionDiv","appear","widthContainer","reactionsContainer","reactionsScrollable","renderReaction","setVisible","canUseAnimations","scaleContainer","appearWrapper","appear_animation","selectLoadPromise","selectPlayer","REACTION_SIZE","ChatContextMenu","onContextMenu","isTextSelected","isAnchorTarget","isUsernameTarget","selectedMid","isOverBubble","isTargetAGroupedItem","viewerPeerId","canOpenReactedList","linkToMessage","getUrlToMessage","selectedMessagesText","getSelectedMessagesText","menuPadding","reactionsMenu","reactionsMenuPosition","isReactionsMenuVisible","offsetSize","nextVisiblePart","MIN_NEXT_VISIBLE_PART","minSize","onSendScheduledClick","onReplyClick","onFaveStickerClick","unfave","faveSticker","onEditClick","getMessageWithText","initMessageEditing","onCopyClick","onCopyAnchorLinkClick","onCopyLinkClick","onUnpinClick","onRetractVote","onStopPoll","stopPoll","setButtons","hasAttribute","notDirect","scheduleSending","editMessage","scheduleDate","canEditMessage","getMessageFromStorage","canSaveMessageMedia","isGoodType","hasTarget","localName","emojiInputsPromise","getUniqueCustomEmojisFromMessage","filterUnique","viewsButton","isViewingReactions","participantsCount","reactedLength","i18nElem","fakeText","AVATAR_SIZE","MAX_AVATARS","PADDING_PER_AVATAR","reactionsCount","fakeElem","readParticipants","totalSize","emojisButton","setPadding","inputsPromise","getCachedCustomEmojiDocuments","getCustomEmojiDocuments","threadMessage","SendMenu","sendMenuButtons","onSilentClick","onScheduleClick","sendMenu","openSide","onContextElement","setPeerId","PopupCreatePoll","onSubmitClick","send","radioLabel","isEmpty","questions","appendMoreField","correctAnswers","optionInputFields","questionInputField","sendSilent","settingsCaption","anonymousCheckboxField","multipleCheckboxField","quizCheckboxField","quizSolutionField","quizElements","quizSolutionCaption","quizHr","quizSolutionContainer","quizSolutionSubtitle","getFilledAnswers","quizSolution","quizSolutionEntities","inputMediaPoll","getInputMediaPoll","sendOther","getMessageSendingParams","helperType","clearHelper","questionField","createPosterFromMedia","getGifDuration","arrayBuffer","USELESS_REG_EXP","InputFieldAnimated","updateInnerHTML","onFakeInput","inputFake","setHeight","currentHeight","onChangeHeight","currentPopup","getCurrentNewMediaPopup","PopupNewMedia","willAttachType","ignoreInputValue","messageInputField","attachFile","willAttach","shouldCompress","itemDiv","defineNotNumerableProperties","attachMedia","attachDocument","sendFileDetails","captionMaxLength","captionLengthMax","changeType","hasAnyMedia","changeGroup","canGroupSomething","changeSpoilers","canToggleSpoilers","isMedia","wasInputValue","attachFiles","applyMediaSpoiler","removeMediaSpoiler","noAnimation","widthStr","heightStr","containerWidthStr","containerHeightStr","strippedBytes","appendDrops","mediaCount","mediaWithSpoilers","addFiles","toPush","_file","lastModified","sendingParams","sendFileParams","sendText","scaledBlob","sendAlbum","replyToMsgId","modifyMimeTypeForTelegram","scaleImageForTelegram","convertWebp","PHOTO_SIDE_LIMIT","objectURL","audioDecodedByteCount","webkitAudioDecodedByteCount","noSound","onseeked","onerror","createPosterFromVideo","scaled","isPhoto","isAudio","onRender","foundPhotos","foundVideos","foundFiles","appendMediaToContainer","firstType","oldSendFileDetails","albumContainer","oldParams","HANDLE_EVENT","ACTIVE_CLASS_NAME","AXIS_Y_KEYS","AXIS_X_KEYS","attachListNavigation","waitForKey","waitForKeySet","keyNames","getCurrentTarget","setCurrentTarget","hadTarget","getNextTargetX","currentTarget","isNext","nextTarget","handleArrowKey","endProperty","currentRect","targetRect","getNextTargetY","fireSelect","canContinue","attached","resetTarget","_onKeyDown","AutocompleteHelper","onVisible","listType","attachNavigation","controller","addHelper","toggleListNavigation","fromController","skipAnimation","hideOtherHelpers","StickersHelper","onChangeScreen","checkEmoticon","getStickersByEmoticon","getMinDate","getMaxDate","PopupSchedule","canSendWhenOnline","btnSendWhenOnline","EmojiHelper","chatInput","onEmojiSelected","checkQuery","firstChar","getBothEmojiKeywords","searchEmojis","AutocompletePeerHelper","doNotShow","listElement","BASE","BASE_CLASS_LIST_ELEMENT","processPeerFullForCommands","botInfos","commands","command","indexObject","CommandsHelper","getReadyToSend","sendMessage","AutocompleteHelperController","preserveHelper","MentionsHelper","insertAtCaret","topMsgId","trimmed","getMentions","ReplyKeyboard","onBodyTouchStart","btnHover","checkAvailability","checkForceReply","touchListener","sendContact","getReplyMarkup","getHistoryStorageTransferable","InlineHelper","queryId","queryAndResultIds","generateQId","resultId","sendInlineResult","_checkQuery","botResults","query_id","gifsMasonry","isGallery","gallery","noCommands","dcId","switch_pm","btnSwitchToPM","switchToPM","ChatBotCommands","setUserId","modifyAckedResult","acked","modifyAckedPromise","ChatSendAs","sendAsButtons","previousAvatar","onSendAsMenuToggle","updateButtons","sendAsPeerId","changeSendAsPeerId","executeButtonsUpdate","sendAsPeerIds","saveDefaultSendAs","updateAvatar","getDefaultSendAs","getChannelFull","channelFull","default_send_as","updateManual","updatingPromise","wasSkippingAnimation","getSendAs","sendAsPeers","sendAsPeer","premium_required","addedListener","hasMarkupInSelection","onlyFull","nodes","commonAncestor","SHOW_ELEMENT","resultBoolean","POSTING_MEDIA_NOT_ALLOWED","ChatInput","lastUrl","lastTimeType","replyElements","willSendWebPage","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","showLinkEditor","onMessageInput","markdownEntities","parseMarkdown","urlEntities","getWebPagePromise","appWebPagesManager","getWebPage","setTopInfo","noWebPage","onHelperCancel","helperFunc","botCommands","resetCurrentFontFormatting","updateBotCommandsToggle","editMsgId","saveDraftDebounced","checkAutocomplete","updateSendBtn","onBtnSendClick","forwarding","restricted","voice_messages_forbidden","releaseMediaPlayback","setRecording","showDiscardPopup","btnCancelRecord","recordingOverlayListener","recordingNavigationItem","sourceNode","analyser","createAnalyser","connect","fftSize","frequencyData","frequencyBinCount","getByteFrequencyData","recordRippleEl","ms","recordTimeEl","needReturn","getCurrentInputAsDraft","no_webpage","originalDraft","canPassEntitiesTypes","draftsAreEqual","onHelperClick","forwardElements","rowsWrapperWrapper","rowsWrapper","fakeRowsWrapper","fakeSelectionWrapper","goDownBtn","controlContainer","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","attachMenuButtons","fileInput","attachMenu","attachMenuBots","appAttachMenuBotsManager","getAttachMenuBots","attachMenuBotsButtons","attachMenuBot","getAttachMenuBotIcon","requestWebView","webViewResultUrl","SANDBOX_ATTRIBUTES","verifyMap","attachMenuPeerTypeSameBotPM","attachMenuPeerTypeBotPM","attachMenuPeerTypePM","attachMenuPeerTypeChat","attachMenuPeerTypeBroadcast","peer_types","multiple","autocompleteHelperController","stickersHelper","emojiHelper","commandsHelper","mentionsHelper","inlineHelper","btnSendContainer","btnSend","attachMessageInputField","previousQuery","saveDraft","encoderSampleRate","monitorGain","numberOfChannels","recordingGain","reuseWorker","onstop","ondataavailable","typedArray","dataBlob","sendFile","isVoiceMessage","botStartBtn","toggleBotStartBtnDisability","startBot","pinnedControlBtn","originalChat","pinnedMessageContainer","_center","neededFakeContainer","fakeWrapperTo","oldFakeWrapperTo","fakeSelectionRect","fakeRowsRect","initTranslateX","getNeededFakeContainer","isReplyInTopicOverlayNeeded","hasMentions","ignoreEmptyValue","syncDraft","helperToo","clearInput","fromUpdate","getDraft","wrappedDraft","myEntities","apiEntities","wrapDraft","currentDraft","createSendAs","firstChange","sendAs","updateOffset","getPlaceholderKey","updateMessageInputPlaceholder","previousSendAs","ackedPeerFull","ackedScheduledMids","setSendAsCallback","filteredAttachMenuButtons","filterAttachMenuButtons","placeholderKey","hasBotCommands","updateBotCommands","updateMessageInput","haveSomethingInControl","isAnonymousSending","oldInputField","attachMessageInputListeners","fixSafariStickyInputFocusing","APP_TABS","CHAT","readAllHistory","commandsMap","canCombine","hasMarkup","executed","resetCurrentFormatting","setActiveMarkupButton","insertText","insertEntity","isHelper","fullValue","AUTO_COMPLETE_REG_EXP","matchIndex","foundHelper","checkInlineAutocomplete","setPreloaderShow","btnPreloader","inlineMatch","bot_inline_placeholder","inlinePlaceholder","helperWaitingForward","canSetDraft","fireEvent","clearValue","fixSafariStickyInput","getValueAndEntities","clearReply","unicode","pushRecentEmoji","dropAuthor","dropCaptions","isDroppingCaptions","sendMessageWithDocument","hideCaptionCheckboxField","replyFragment","initMessagesForward","fromPeerIdsMids","fromPeerIds","smth","messagesWithCaptionsLength","peerTitles","titleKey","senderTitles","firstMessage","newReply","intl","peerTitleEl","_message","setReplyToMsgId","callerFunc","replyParent","oldReply","haveReply","CLASSNAME_BASE","PinnedContainer","floating","divAndCaption","wrapperUtils","attachOnCloseEvent","needClose","setFloating","setUtilsWidth","BAR_HEIGHTS","ChatAudio","onPlaybackParams","fasterEl","repeatEl","toggleEl","onStop","onMediaPlay","isMusic","prevEl","nextEl","attachClick","volumeProgressLineContainer","tunnel","progressWrapper","playingDetails","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","isLast","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","beforeDestroy","cleanupBackground","destroySharedMediaTab","searchTab","_isAnyGroup","setAutoDownloadMedia","getForumTopicOrReload","isSamePeer","bubblesSetPeerPromise","photoSizeMax","videoSizeMax","fileSizeMax","photo_size_max","video_size_max","getAutoDownloadSettingsByPeerId","callbacksPromise","ignoreThreadId","historyStorageTransferable","historySerialized","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","kickFromChat","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","AppImManager","columnEl","offline","updateStatusInterval","cacheStorage","saveState","onHashChangeUnsafe","tgaddr","openUrl","postId","openUsername","userName","setSettings","messagesTextSize","forceRenderAfterSize","chatsSelectTabDebounced","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","stateStorage","topbarCall","discardCurrentCall","currentCall","setAuthorized","telegramMeWebManager","hashtag","STICKER_SET","EMOJI_SET","makeLink","INVOICE","VOICE_CHAT","USER_PHONE_NUMBER","thread","PRIVATE_POST","channel","comment","getStackFromElement","MESSAGE","attachKeydownListener","handleAutologinDomains","checkForShare","share","foundMedia","openWindow","onUrlAuthResult","urlAuthResult","botPeerTitle","logInCheckbox","allowMessagesCheckbox","request_write_access","confirmationPromise","logInChecked","allowMessagesChecked","acceptUrlAuth","onUrlAuthResultAccepted","requestUrlAuth","_appConfig","onAnchorClick","url_auth_domains","autologin_token","autologin_domains","originalUrl","searchParams","possibleBubble","timeoutOperation","requests","request","isBad","activatingChat","screen","IGNORE_KEYS","isSelectionCollapsed","getFirstMessageToEdit","getNextDialog","newEvent","KeyboardEvent","commentId","resolveChannel","op","checkChatInvite","saveApiChat","resolvePhone","getInputInvoiceBySlug","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","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","DialogColorsFg","DialogColors","DialogColorsMap","pic","peerParams","useBytes","bestPhotoSize","CallConnectionInstanceBase","connection","sources","createPeerConnection","config","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","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","wrap","_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","setLoop","_autoplay","loadLottieWorkers","remain","Worker","queryableWorker","makeAssetUrl","loadAnimationAsAsset","loadAnimationFromURL","loadAnimationDataFromURL","blobConstruct","loadAnimationFromURLManually","loadAnimationFromURLNext","newParams","loadAnimationWorker","waitForFirstFrame","initPlayer","destroyWorkers","loadFromData","getLottiePixelRatio","RLottiePlayer","cachingDelta","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":""}