#include <bits/stdc++.h>
using namespace std;
inline long long read() {
  long long x = 0;
  int ch = getchar(), f = 1;
  while (!isdigit(ch) && (ch != '-') && (ch != EOF)) ch = getchar();
  if (ch == '-') {
    f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 1) + (x << 3) + ch - '0';
    ch = getchar();
  }
  return x * f;
}
const int N = 5e5 + 10, mod = 1e9 + 7;
int n, ans;
pair<int, int> a[N];
inline int Mod(int x) { return x >= mod ? x - mod : x; }
inline void upd(int &x, int y) {
  x += y, x = (x >= mod ? x - mod : (x < 0 ? x + mod : x));
}
struct SegmentTree {
  int v[N << 2], lazy[N << 2];
  inline void push_up(int u) { v[u] = Mod(v[u << 1] + v[u << 1 ^ 1]); }
  inline void push_down(int u, int l, int mid, int r) {
    if (!lazy[u]) return;
    upd(lazy[u << 1], lazy[u]), upd(lazy[u << 1 ^ 1], lazy[u]);
    upd(v[u << 1], 1ll * lazy[u] * (mid - l + 1) % mod),
        upd(v[u << 1 ^ 1], 1ll * lazy[u] * (r - mid) % mod);
    lazy[u] = 0;
  }
  inline void update(int u, int l, int r, int ql, int qr) {
    if (l >= ql && r <= qr)
      return upd(v[u], r - l + 1), upd(lazy[u], 1), void(0);
    int mid = l + r >> 1;
    push_down(u, l, mid, r);
    if (qr <= mid)
      update(u << 1, l, mid, ql, qr);
    else if (ql > mid)
      update(u << 1 ^ 1, mid + 1, r, ql, qr);
    else
      update(u << 1, l, mid, ql, qr), update(u << 1 ^ 1, mid + 1, r, ql, qr);
    push_up(u);
  }
  inline int Query(int u, int l, int r, int ql, int qr) {
    if (l >= ql && r <= qr) return v[u];
    int mid = l + r >> 1;
    push_down(u, l, mid, r);
    if (qr <= mid)
      return Query(u << 1, l, mid, ql, qr);
    else if (ql > mid)
      return Query(u << 1 ^ 1, mid + 1, r, ql, qr);
    else
      return Mod(Query(u << 1, l, mid, ql, qr) +
                 Query(u << 1 ^ 1, mid + 1, r, ql, qr));
  }
} t[2];
int main() {
  n = read();
  for (register int i = (1); i <= (n); i++) a[i] = make_pair(read(), i);
  sort(a + 1, a + 1 + n);
  for (register int i = (1); i <= (n); i++) {
    int x = t[0].Query(1, 1, n, a[i].second, a[i].second),
        sum = t[0].Query(1, 1, n, 1, a[i].second);
    int y = t[1].Query(1, 1, n, a[i].second, a[i].second),
        Sum = t[1].Query(1, 1, n, a[i].second, n);
    upd(ans, 1ll * a[i].first *
                 (sum - 1ll * x * a[i].second % mod + a[i].second) % mod *
                 (n - a[i].second + 1) % mod);
    upd(ans, 1ll * a[i].first * (Sum - 1ll * y * (n - a[i].second + 1) % mod) %
                 mod * a[i].second % mod);
    t[0].update(1, 1, n, 1, a[i].second), t[1].update(1, 1, n, a[i].second, n);
  }
  printf("%d\n", ans);
}
