-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.vue
More file actions
196 lines (181 loc) · 7.46 KB
/
app.vue
File metadata and controls
196 lines (181 loc) · 7.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
<template>
<Analytics />
<SpeedInsights />
<UApp>
<div class="flex items-center min-h-screen">
<div class="flex flex-col mt-15 md:mt-0 md:flex-row 2xl:mx-30 xl:mx-10 mx-6 text-white 2xl:gap-20 xl:gap-10 lg:gap-5 md:gap-3">
<div class="md:w-[50%]">
<header>
<div class="md:flex hidden items-center gap-5">
<h1 class="font-bold 2xl:text-5xl xl:text-5xl lg:text-4xl md:text-3xl">Busted for <span>Cheating</span></h1>
<img src="/media/bfc-eye.webp" class="h-10 2xl:h-15 xl:h-15 lg:h-10 md:h-8" alt="Logo" />
</div>
<div class="md:hidden text-center items-center">
<img src="/media/bfc-eye.webp" class="h-10 mx-auto" alt="Logo" />
<h1 class="font-bold text-4xl">Busted for <span>Cheating</span></h1>
</div>
<h2 class="text-center md:text-left text-xl xl:text-2xl md:text-base mt-5 md:mt-0"><span>Online exams</span> and web apps know when you cheat.</h2>
</header>
<div class="mt-15 md:mt-25 2xl:text-xl xl:text-xl md:text-base text-base">
<p>
Since <span>2011</span>, a small <span>JavaScript feature</span> has quietly allowed websites
to<br><span>detect when you're actively viewing a tab</span>.<br>Originally meant for pausing videos or saving battery,
it's now used by test platforms to catch cheaters switching tabs or becoming inactive.
</p>
<p class="mt-10">In just <span>a few lines of code</span>,<br>any website can know when you're <span>paying attention — or not.</span></p>
</div>
<USeparator color="primary" class="mt-15 md:mt-[5%]" />
<footer class="md:flex hidden items-center mt-28">
<p class="2xl:text-xl xl:text-xl">
Made by <a href="https://github.com/PetyXbron">PetyXbron</a> © 2025
| <a href="https://choosealicense.com/licenses/mit/" target="_blank">MIT</a>
|
</p>
<a href="https://github.com/PetyXbron/BustedForCheating" target="_blank">
<Icon name="akar-icons:github-fill" size="20px" class="ml-2 xl:ml-1 flex justify-center" />
</a>
<a href="https://dsc.gg/azator" target="_blank">
<Icon name="akar-icons:discord-fill" size="20px" class="ml-2 xl:ml-1 flex justify-center" />
</a>
<a href="https://twitter.com/intent/tweet?text=I%20just%20found%20BFC!%20Check%20it%20out!&url=https%3A%2F%2Fbfc.arim.dev&hashtags=education,cheating,chatgpt,ai" target="_blank">
<Icon name="akar-icons:x-fill" size="20px" class="ml-2 xl:ml-1 flex justify-center" />
</a>
</footer>
</div>
<div class="mt-15 md:mt-0 md:w-[50%]">
<div>
<div class="text-center">
<h1 class="text-2xl 2xl:text-4xl xl:text-3xl md:text-2xl"><span>Try it</span> yourself.</h1>
<h2 class="2xl:text-xl xl:text-lg md:text-base">This logs every event about your view activity.</h2>
</div>
<div id="log" class="p-10 xl:p-6 md:p-4 mt-5 w-full rounded-lg max-h-[64vh] min-h-[64vh] overflow-y-auto" style="background-color: #161A1D;">
<div v-for="(change, index) in limitedChanges" :key="index" class="2xl:text-base xl:text-base lg:text-sm md:text-sm mb-2">
<span style="color: #D3D3D3 !important">[{{ getRelativeTime(change.time) }}]</span> <span>{{ change.event }}</span>
</div>
</div>
</div>
<div class="block md:hidden">
<USeparator color="primary" class="mt-15 md:mt-[5%]" />
<footer class="flex justify-center items-center my-28">
<p class="2xl:text-xl xl:text-xl">
Made by <a href="https://github.com/PetyXbron">PetyXbron</a> © 2025
| <a href="https://choosealicense.com/licenses/mit/" target="_blank">MIT</a>
|
</p>
<a href="https://github.com/PetyXbron/BustedForCheating" target="_blank">
<Icon name="akar-icons:github-fill" size="20px" class="ml-2 xl:ml-1 flex justify-center" />
</a>
<a href="https://dsc.gg/azator" target="_blank">
<Icon name="akar-icons:discord-fill" size="20px" class="ml-2 xl:ml-1 flex justify-center" />
</a>
<a href="https://twitter.com/intent/tweet?text=I%20just%20found%20BFC!%20Check%20it%20out!&url=https%3A%2F%2Fbfc.arim.dev&hashtags=education,cheating,chatgpt,ai" target="_blank">
<Icon name="akar-icons:x-fill" size="20px" class="ml-2 xl:ml-1 flex justify-center" />
</a>
</footer>
</div>
</div>
</div>
</div>
<div v-show="cookiesConsent" style="background-color: #161A1D;" class="fixed bottom-0 left-0 p-3 rounded-lg text-white flex flex-col justify-between md:w-[35%] mx-5 md:ml-5 h-[25%] mb-5">
<div>
<h1 class="font-bold 2xl:text-3xl xl:text-3xl lg:text-2xl md:text-xl"><span>Cookies consent</span></h1>
<p>
We use cookies to analyze traffic and improve your experience.<br>You can accept or reject their use.
</p>
</div>
<div>
<div class="flex gap-3 bottom-0">
<button @click="acceptCookies" class="bg-redbow-500 w-[50%] rounded-md p-2 cursor-pointer hover:bg-redbow-600 transition-colors duration-300">Accept</button>
<button @click="denyCookies" class="bg-redbow-500 w-[50%] rounded-md p-2 cursor-pointer hover:bg-redbow-600 transition-colors duration-300">Deny</button>
</div>
</div>
</div>
</UApp>
</template>
<script setup lang="ts">
import { Analytics } from '@vercel/analytics/nuxt';
import { SpeedInsights } from "@vercel/speed-insights/nuxt";
const changes = ref<Array<{ time: number, event: string }>>([])
const timer = ref<ReturnType<typeof setInterval>>()
const cookiesConsent = ref(false)
// Function to get relative time in seconds
const getRelativeTime = (timestamp: number): string => {
const seconds = Math.floor((Date.now() - timestamp) / 1000)
return `${seconds}s ago`
}
// Event listeners
onMounted(() => {
// Fetch cookies consent localStorage
const savedConsent = localStorage.getItem('cookiesAccepted')
if (!savedConsent) {
cookiesConsent.value = true
}
// Log first event
changes.value.unshift({
time: Date.now(),
event: 'Opened the page'
})
document.title = 'BFC | Tab active'
// Add 1 second interval
timer.value = setInterval(() => {
if (changes.value.length > 0) {
changes.value = [...changes.value]
}
}, 1000)
// Leave tab or window event
window.addEventListener('blur', () => {
changes.value.unshift({
time: Date.now(),
event: 'Left tab or window'
})
document.title = 'BFC | Tab closed'
})
// Return to tab or window event
window.addEventListener('focus', () => {
changes.value.unshift({
time: Date.now(),
event: 'Returned to tab or window'
})
document.title = 'BFC | Tab active'
})
// Another way to detect tab visibility changes
/* document.addEventListener('visibilitychange', () => {
changes.value.unshift({
time: Date.now(),
event: document.hidden ? 'switched tabs' : 'returned to tab'
})
})*/
})
// Cleanup event listeners
onUnmounted(() => {
if (timer.value) {
clearInterval(timer.value)
}
})
// Limitting the number of changes displayed
const limitedChanges = computed(() => {
return changes.value.slice(0, 50)
})
// Google consent mode
const { gtag } = useGtag()
function acceptCookies() {
gtag('consent', 'update', {
ad_user_data: 'granted',
ad_personalization: 'granted',
ad_storage: 'granted',
analytics_storage: 'granted'
})
localStorage.setItem('cookiesAccepted', 'true')
cookiesConsent.value = false
}
function denyCookies() {
gtag('consent', 'update', {
ad_user_data: 'denied',
ad_personalization: 'denied',
ad_storage: 'denied',
analytics_storage: 'denied'
})
localStorage.setItem('cookiesAccepted', 'false')
cookiesConsent.value = false
}
</script>