/**
E - Easy Sequence
题意:给出一个左右括号序列,设ANSi是第i个括号所在的有效括号对的数量,有效括号对指的是(),()(),(())这样
的形式要求 sum { ANSi * i % mod | 1 <= i <= n }, 注意是求每个i先取模之后的和,不是所有和取模
思路:一开始看成是求出所有和再取模,直接求贡献去了然后WA,首先如果一个左括号是在一个有效括号对内,它
有唯一一个右括号与之配对,所以可以用栈找出所有有效括号对,而且对于一个括号如果包含在某个有效括号对内,
这个最小的有效括号对是唯一的,那么对于一个有效括号对(待讨论的用[]表示),左括号和右括号的ans是一样的,
只讨论左括号,那么(..)(..)[..](..)(..),这样的对ans提供(左边括号数 + 1) * (右边括号数 + 1) = x1,(([..]))
这样的提供内层的ans' = x2,所以他的ans = x1 + x2,x1也可以用栈记录这些区间求得,对于x2记录每个括号的父
括号的ans值即可
**/
#include<bits/stdc++.h>
typedef long long ll;
const int maxn = 1e6 + 10;
const ll mod = 1e9 + 7;
using namespace std;
typedef pair<int, int> pa;
char str[maxn];
int T, stk[maxn], pre[maxn], nxt[maxn];
ll suml[maxn], sumr[maxn], rec[maxn];
pa res[maxn];
int main() {
scanf("%d", &T);
while(T--) {
scanf("%s", str + 1);
int len = strlen(str + 1), x = 0, ind, tot = 1;
ll ans = 0;
for(int i = 1; i <= len; i++) {
char c = str[i]; ind = i; nxt[i] = pre[i] = 0;
if(c == '(') { stk[x++] = i; continue; }
if(x && str[stk[x - 1]] == '(') {
x--; ind = stk[x];
int l = ind, r = i;
nxt[l] = r;
while(tot > 1 && res[tot - 1].first >= l && res[tot - 1].second <= r) {
tot--; pa now = res[tot];
pre[now.first] = l;
if(now.second == res[tot + 1].first - 1) sumr[tot] = sumr[tot + 1] + 1;
else sumr[tot] = 1;
ll val = suml[tot] * sumr[tot];
rec[now.first] = val;
}
if(tot > 1 && res[tot - 1].second == l - 1) suml[tot] = suml[tot - 1] + 1;
else suml[tot] = 1;
res[tot++] = pa(l, r); res[tot] = pa(len + len, len + len);
} else stk[x++] = i;
}
for(int i = tot - 1; i >= 1; i--) {
pa now = res[i], nxt = res[i + 1];
if(now.second == nxt.first - 1) sumr[i] = sumr[i + 1] + 1;
else sumr[i] = 1;
ll val = suml[i] * sumr[i];
rec[now.first] = val;
}
for(int i = 1; i <= len; i++) {
if(str[i] == ')' || !nxt[i]) continue;
ll x = i, y = nxt[i];
rec[i] = (rec[i] + rec[pre[i]]) % mod;
ans += x * rec[i] % mod;
ans += y * rec[i] % mod;
}
printf("%lld\n", ans);
}
return 0;
}