#include <bits/stdc++.h>
const int MOD = 1e9 + 7;
const int INF = 1e9 + 7;
const int N = 5e5 + 5;
const int M = 2e5 + 5;
using namespace std;
int tree[4 * N];
long long int stree[4 * N], lz[4 * N];
void upd(int pos, int val, int node, int st, int en) {
  if (st == en) {
    tree[node] += val;
    return;
  }
  int m = (st + en) / 2;
  if (pos <= m)
    upd(pos, val, 2 * node + 1, st, m);
  else
    upd(pos, val, 2 * node + 2, m + 1, en);
  tree[node] = tree[2 * node + 1] + tree[2 * node + 2];
}
long long int query(int l, int r, int node, int st, int en) {
  if (l > en || r < st) return 0;
  if (st >= l && en <= r) return tree[node];
  int m = (st + en) / 2;
  return query(l, r, 2 * node + 1, st, m) +
         query(l, r, 2 * node + 2, m + 1, en);
}
void supd(int l, int r, long long int val, int node, int st, int en) {
  if (lz[node] > 0) {
    stree[node] += (lz[node] * (en - st + 1)) % MOD;
    if (stree[node] >= MOD) stree[node] -= MOD;
    if (st != en) {
      lz[2 * node + 1] += lz[node];
      if (lz[2 * node + 1] >= MOD) lz[2 * node + 1] -= MOD;
      lz[2 * node + 2] += lz[node];
      if (lz[2 * node + 2] >= MOD) lz[2 * node + 2] -= MOD;
    }
    lz[node] = 0;
  }
  if (st > r || en < l) return;
  if (st == en) {
    stree[node] += (val + lz[node]) % MOD;
    if (stree[node] >= MOD) stree[node] -= MOD;
    lz[node] = 0;
    return;
  }
  int m = (st + en) / 2;
  if (st >= l && en <= r) {
    stree[node] += (val * (en - st + 1)) % MOD;
    if (stree[node] >= MOD) stree[node] -= MOD;
    lz[2 * node + 1] += val;
    if (lz[2 * node + 1] >= MOD) lz[2 * node + 1] -= MOD;
    lz[2 * node + 2] += val;
    if (lz[2 * node + 2] >= MOD) lz[2 * node + 2] -= MOD;
    return;
  }
  supd(l, r, val, 2 * node + 1, st, m);
  supd(l, r, val, 2 * node + 2, m + 1, en);
  stree[node] = stree[2 * node + 1] + stree[2 * node + 2];
  if (stree[node] >= MOD) stree[node] -= MOD;
}
long long int squery(int l, int r, int node, int st, int en) {
  if (l > en || r < st) return 0;
  int m = (st + en) / 2;
  if (lz[node] > 0) {
    stree[node] += (lz[node] * (en - st + 1)) % MOD;
    if (stree[node] >= MOD) stree[node] -= MOD;
    if (st != en) {
      lz[2 * node + 1] += lz[node];
      if (lz[2 * node + 1] >= MOD) lz[2 * node + 1] -= MOD;
      lz[2 * node + 2] += lz[node];
      if (lz[2 * node + 2] >= MOD) lz[2 * node + 2] -= MOD;
    }
    lz[node] = 0;
  }
  if (st >= l && en <= r) {
    return stree[node];
  }
  long long int ans =
      squery(l, r, 2 * node + 1, st, m) + squery(l, r, 2 * node + 2, m + 1, en);
  if (ans >= MOD) ans -= MOD;
  return ans;
}
void solve() {
  int n, i;
  cin >> n;
  vector<pair<int, int>> v(n);
  for (i = 0; i < n; i++) {
    int x;
    cin >> x;
    v[i] = {x, i + 1};
  }
  sort(v.begin(), v.end());
  long long int ans = 0;
  for (auto it : v) {
    long long int y = it.second;
    upd(y, 1, 0, 0, n);
    supd(y, n, 1, 0, 0, n);
    long long int lcnt =
        (y * query(0, y, 0, 0, n) - squery(0, y - 1, 0, 0, n)) % MOD;
    if (lcnt < 0) lcnt += MOD;
    long long int rcnt =
        (squery(y, n, 0, 0, n) - (n - y + 1) * query(0, y, 0, 0, n)) % MOD;
    if (rcnt < 0) rcnt += MOD;
    ans += (((lcnt * (n - y + 1) + rcnt * y) % MOD) * it.first) % MOD;
    if (ans >= MOD) ans -= MOD;
  }
  cout << ans << '\n';
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  ;
  int t = 1;
  for (int tc = 1; tc <= t; tc++) {
    solve();
  }
  return 0;
}
