diff --git a/README.md b/README.md
index 1bad263..047c42b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,4 @@
-# jspsych-npm-template
+# Suspicion-probe Experiment 1
+
+
diff --git a/images/blue/instructions_1.png b/images/blue/instructions_1.png
new file mode 100644
index 0000000..ea2a49f
Binary files /dev/null and b/images/blue/instructions_1.png differ
diff --git a/images/blue/instructions_2.png b/images/blue/instructions_2.png
new file mode 100644
index 0000000..15240ed
Binary files /dev/null and b/images/blue/instructions_2.png differ
diff --git a/images/blue/instructions_3.png b/images/blue/instructions_3.png
new file mode 100644
index 0000000..f5d7f2f
Binary files /dev/null and b/images/blue/instructions_3.png differ
diff --git a/images/blue/instructions_4.png b/images/blue/instructions_4.png
new file mode 100644
index 0000000..6f4ec11
Binary files /dev/null and b/images/blue/instructions_4.png differ
diff --git a/images/instruction_images.afphoto b/images/instruction_images.afphoto
new file mode 100644
index 0000000..ae97cc9
Binary files /dev/null and b/images/instruction_images.afphoto differ
diff --git a/images/red/instructions_1.png b/images/red/instructions_1.png
new file mode 100644
index 0000000..910b5fa
Binary files /dev/null and b/images/red/instructions_1.png differ
diff --git a/images/red/instructions_2.png b/images/red/instructions_2.png
new file mode 100644
index 0000000..01584fc
Binary files /dev/null and b/images/red/instructions_2.png differ
diff --git a/images/red/instructions_3.png b/images/red/instructions_3.png
new file mode 100644
index 0000000..18d9e2f
Binary files /dev/null and b/images/red/instructions_3.png differ
diff --git a/images/red/instructions_4.png b/images/red/instructions_4.png
new file mode 100644
index 0000000..db5e98d
Binary files /dev/null and b/images/red/instructions_4.png differ
diff --git a/index.js b/index.js
index b8c6dce..fb302f3 100644
--- a/index.js
+++ b/index.js
@@ -1,11 +1,31 @@
-import { initJsPsych } from "jspsych";
-import "jspsych/css/jspsych.css";
-import "./styles.css";
-import { delayed_redirect } from "./utils/helpers.js";
-import jsPsychHtmlKeyboardResponse from "@jspsych/plugin-html-keyboard-response";
-import { textStimuli } from './scripts/text_stimuli';
+import { initJsPsych } from 'jspsych';
+import 'jspsych/css/jspsych.css';
+import jsPsychHtmlKeyboardResponse from '@jspsych/plugin-html-keyboard-response';
+import generateUniqueUsernames from './scripts/name-gen.js';
+import jsPsychFullscreen from '@jspsych/plugin-fullscreen';
+import jsPsychHtmlButtonResponse from '@jspsych/plugin-html-button-response';
+import jsPsychLobby from './scripts/plugin-lobby.js';
+import jsPsychSurvey from '@jspsych/plugin-survey';
+import '@jspsych/plugin-survey/css/survey.css';
+import './styles.css';
+import { getStimulusMap } from './scripts/text-stimuli.js';
+import jsPsychObjectMoving from './scripts/plugin-object-moving.js';
-const debug = import.meta.env.VITE_DEBUG;
+const debug = import.meta.env.VITE_DEBUG === 'true';
+const total_participants = import.meta.env.VITE_TOTAL_PARTICIPANTS;
+const uniqueUsernames = generateUniqueUsernames(total_participants);
+const experiment_name = import.meta.env.VITE_EXPERIMENT_NAME;
+
+let prolific_id;
+let probe_condition; // P in the params, O = open, S = suspicion mentioned
+let mapping; // M in the params, TB = together blue, AB = alone blue
+let short_version = false;
+
+function delayed_redirect(url) {
+ setTimeout(() => {
+ window.location = url;
+ }, 5000);
+}
const jsPsych = initJsPsych({
on_finish: function() {
@@ -21,12 +41,309 @@ const jsPsych = initJsPsych({
},
});
-const demo_trial = {
+prolific_id = jsPsych.data.getURLVariable('PROLIFIC_PID');
+mapping = jsPsych.data.getURLVariable('M');
+short_version = jsPsych.data.getURLVariable('S') === 'true';
+const together_colour = mapping === 'TB' ? 'blue' : 'red';
+const stimulusMap = getStimulusMap(together_colour);
+
+probe_condition = jsPsych.data.getURLVariable('P');
+let probe_text;
+if (probe_condition === 'O') {
+ probe_text =
+ 'Did you have any thoughts or observations about the experiment?';
+} else if (probe_condition === 'S') {
+ probe_text =
+ 'Did you have any thoughts, observations, or suspicions about the experiment?';
+} else if (probe_condition === 'D') {
+ probe_text =
+ 'Many studies use deception to create the appearance that you are interacting with a real person. Did you suspect that you were not interacting with a real person?';
+} else if (probe_condition === 'R') {
+ probe_text =
+ 'Our study used deception to create the appearance that you are interacting with a real person. Did you suspect that you were not interacting with a real person?';
+} else {
+ probe_text =
+ 'Did you have any thoughts or observations about the experiment?';
+}
+
+jsPsych.data.addProperties({
+ condition: probe_condition,
+ together_colour: together_colour,
+ prolific_id: prolific_id,
+ experiment_name: experiment_name,
+ probe_text: probe_text,
+});
+
+const timeline = [];
+
+const pre_consent_info = {
type: jsPsychHtmlKeyboardResponse,
- stimulus: `
`;
+ go_button = document.getElementById('go-button');
+ object_participant.addEventListener('click', () => issue_alert('early_click_go'));
+ go_button.addEventListener('click', () => handle_go_click(go_button));
+ }
+
+ function handle_go_click() {
+ go_button.removeEventListener('click', handle_go_click);
+ go_button.removeEventListener('click', () => issue_alert('early_click_go'));
+ go_clicked = true;
+ go_button.remove();
+ change_object_colour(object_participant);
+ object_participant.addEventListener('click', () => handle_teleport_click());
+
+ }
+
+ function handle_teleport_click(){
+ teleport_object(object_participant);
+ participant_finished = true;
+ check_finished();
+ }
+
+
+ function change_object_colour(object){
+ object.classList.remove(colourMap.get('object-disabled'));
+ object.classList.add(colourMap.get('object-enabled'));
+ }
+
+ function teleport_object(object){
+ let goal_side = 'left';
+ if (choice === 'together' && trial.together_side === 'right') {
+ goal_side = 'right';
+ }
+ if (choice === 'alone' && trial.together_side === 'left') {
+ goal_side = 'right';
+ }
+ const mid_goal_offset = viewport_width * (1/24);
+ const new_left_offset = goal_side === 'left' ? mid_goal_offset - box_width/2 : viewport_width - mid_goal_offset - box_width/2;
+ object.style.transition = 'left 0.35s';
+ object.style.left = `${new_left_offset}px`;
+ }
+
+ function check_finished(){
+ let finished = false;
+ if (choice === 'together') {
+ if (partner_finished && participant_finished) {
+ finished = true;
+ }
+ }
+ if (choice === 'alone') {
+ if (partner_finished || participant_finished) {
+ finished = true;
+ }
+ }
+ if (finished) {
+ object_partner.removeEventListener('click', () => issue_alert('partner_click'));
+ object_participant.removeEventListener('click', () => issue_alert('early_click_choice'));
+
+ const save_data = {
+ choice: choice,
+ selector: trial.selector,
+ together_side: trial.together_side,
+ response_time: response_time,
+ }
+
+
+ setTimeout(() => {
+ jsPsych.finishTrial(save_data);
+ }, 500);
+ }
+ }
+
+ async function show_alert(message) {
+ const dialog = document.createElement("dialog");
+ document.body.appendChild(dialog);
+ dialog.className = "z-20 fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 p-4 bg-slate-100 text-red-700 rounded-lg shadow-lg";
+ dialog.innerText = message;
+ dialog.show();
+ setTimeout(function () {
+ dialog.close();
+ }, 2000);
+ }
+
+ function issue_alert(issue){
+ if (issue === 'partner_click'){
+ show_alert(`That is your partner's object. Please click the lower object.`)
+ }
+ if (issue === 'early_click_go' && !go_clicked){
+ show_alert(`You need to click 'Go' before clicking your object.`)
+ }
+ if (issue === 'early_click_choice'){
+ if (!partner_choice_made && trial.selector === 'partner'){
+ show_alert(`Please wait for your partner to make a choice.`)
+ }
+ if (!choice && trial.selector === 'participant'){
+ show_alert(`Please make a choice using the buttons below before clicking your object.`)
+ }
+ }
+ }
+
+ }
+}
+
+export default jsPsychObjectMoving;
+
+
+
\ No newline at end of file
diff --git a/scripts/text-stimuli.js b/scripts/text-stimuli.js
new file mode 100644
index 0000000..35ddf8f
--- /dev/null
+++ b/scripts/text-stimuli.js
@@ -0,0 +1,370 @@
+import getColourMap from './colours.js';
+
+// Define image URLs
+const blueImages = {
+ instructions_1: '/images/blue/instructions_1.png',
+ instructions_2: '/images/blue/instructions_2.png',
+ instructions_3: '/images/blue/instructions_3.png',
+ instructions_4: '/images/blue/instructions_4.png',
+};
+
+const redImages = {
+ instructions_1: '/images/red/instructions_1.png',
+ instructions_2: '/images/red/instructions_2.png',
+ instructions_3: '/images/red/instructions_3.png',
+ instructions_4: '/images/red/instructions_4.png',
+};
+
+const html = (strings, ...values) =>
+ strings
+ .reduce((result, str, i) => result + str + (values[i] || ''), '')
+ .trim();
+
+function getStimulusMap(together_colour) {
+ const colourMap = getColourMap(together_colour);
+
+ const stimulusMap = new Map();
+
+ // Select the appropriate image map based on the color
+ const imageMap = together_colour === 'blue' ? blueImages : redImages;
+
+ stimulusMap.set(
+ 'pre_consent_info',
+ html`
+
+ This experiment will need some browser permissions. Please ensure that,
+ when prompted, you allow the experiment to run in fullscreen and that
+ you allow yourself to be redirected to Prolific after the experiment is
+ complete.
+
+ Title of the study: Decision-making with Others
+
+
1. Description of the research project
+ Welcome to our study on Decision-making with Others. We are
+ investigating how people choose courses of action when working with
+ others. The experiment will take less than 20 minutes, with short pauses
+ in between. However, since this is a multi-participant study, we ask
+ that you complete the task fully without taking additional breaks. If
+ you have any further questions, please contact the investigator.
+
+ 2. Voluntary participation and anonymity
+
+ Participation in the study is voluntary. You can withdraw your consent
+ to participate in this study at any time and without giving reasons and
+ without suffering any disadvantages. Even if you terminate the study
+ early, you are entitled to compensation for your time up to that point.
+
3. Compensation
+ For participating in the study, you will receive the rate indicated on
+ the Prolific.com page for this study. The fee will be paid through the
+ Prolific platform.
+
+ 4. Scope of data collection and processing
+
+ We will save your responses and judgements to the questions and stimuli
+ presented in this study. We will also collect information about your
+ response times. We also ask for your gender, age, and thoughts about the
+ study following completion. These data will be de-identified, so that
+ your responses are not saved in a way that one could identify you from
+ your responses (or which responses are yours). The results and data of
+ this study will be published as a scientific publication. This will be
+ done in an anonymized form, i.e. without the data being assigned to a
+ specific person. The completely anonymized data of this study will be
+ made available as open data in a secure, internet-based data archive
+ (osf.io). This study thus follows the recommendations of the German
+ Research Foundation (DFG) and the German Society for Psychology (DGPs)
+ for quality assurance in research.
+
5. Legal basis
+ The legal basis for processing the personal data mentioned is the
+ consent in accordance with Art. 6 (1) letter a EU GDPR.
+
6. Revocation
+ You have the right to revoke your consent to data protection at any
+ time. The revocation of your consent does not affect the legality of the
+ processing carried out on the basis of your consent until the
+ revocation. (Revocation with effect for the future). Address your
+ revocation to the person responsible. You will not suffer any
+ disadvantages as a result of the revocation
+
+ 7. Name and Address of the person responsible
+
+ The controller within the meaning of the EU General Data Protection
+ Regulation (GDPR) and other national data protection laws of the member
+ states, as well as other data protection regulations is the Westfälische
+ Wilhelms-Universität Münster (WWU), represented by the Rector, Prof. Dr.
+ Johannes Wessels, Schlossplatz 2, 48149 MünsterTel.: + 49 251
+ 83-0E-Mail: verwaltung@uni-muenster.de
+
+ 8. Contact details of the data protection officer
+
+ The data protection officer of the WWU Münster is: Nina Meyer-Pachur
+ Schlossplatz 2, 48149 Münster Tel.: + 49 251 83-22446 E-Mail:
+ datenschutz@uni-muenster.de
+
+ 9. Reference to the rights of those affected
+
+
+ According to the General Data Protection Regulation, you basically
+ have the right to: information (Article 15 GDPR), objection (Article
+ 21 GDPR), data portability (Article 20 GDPR), erasure (Article 17
+ GDPR), restriction of processing (Article 18 GDPR), rectification
+ (Article 16 GDPR). If you would like to exercise one of these rights,
+ please contact one of the contact persons mentioned. You also have the
+ right to lodge a complaint with the supervisory authority: State
+ Commissioner for Data Protection and Freedom of Information North
+ Rhine-Westphalia Helga Block Kavalleriestraße 2-440213
+ DüsseldorfTelephone: 02 11/384 24-0E-Mail: poststelle@ldi.nrw.de
+ Homepage: http://www.ldi.nrw.de
+
+
+
+ 10. Consent to the collection and processing of personal data
+
+ By clicking continue, I hereby voluntarily consent to the collection and
+ processing of my personal data as part of the research project
+ ‘Decision-making with others’. I have read the data protection
+ declaration for the project in question, have been adequately informed
+ and have had the opportunity to ask questions. I have been informed of
+ the consequences of revoking my consent under data protection law at any
+ time. I have been informed that my revocation of my consent does not
+ affect the legality of the processing carried out on the basis of the
+ consent up to the time of revocation.
+
+ You are being redirected to Prolific. If you are not redirected within 10 seconds, please paste the following link into your browser:
+
+ ${import.meta.env.VITE_NO_CONSENT_URL}
+
+
+ In this experiment, you will connect and work with a partner.
+
+
+ It is
+ critical
+ that you only continue if you are able to complete the entire experiment
+ without interruption and with a stable internet connection.
+
+
+ Press
+ SPACE
+ once you are ready to be paired with a partner.
+
+ One of the goals (labelled
+
+ Together)
+ will require both of you to move an object each. The other goal
+ (labelled
+
+ Alone)
+ will
+ only
+ require the Selector to move an object.
+
+
+ When you are the Selector, you will see two buttons at the bottom of your
+ screen. The buttons colours correspond to the colour of the goal location
+ (e.g., red button for the red goal).
+
+ If you are not the Selector, you will need to wait until your partner
+ makes a decision.
+
+
+ Once a decision is made, you will first need to click the
+ Go
+ button to make your object movable. Then, once you click an object, it
+ will teleport to the goal location.
+
+ If the Selector chooses the
+ Alone
+ goal, one object will disappear, and the Selector will move the
+ remaining object.
+
+
+ Otherwise, if the Selector chooses
+
+ Together
+
+ , each of you will need to click an object - only click the object that
+ is lower on your screen. The other is for your partner.
+
+ Title of the study: Decision-making with others
+
+
+ Thank you for participating in our study. In this study, we seek to
+ investigate 1) to what extent online participants suspect that their
+ interaction partners are not real people and 2) how and when they
+ report such suspicions.
+
+
+ To this end, we created the appearance of additional participants in
+ the experiment – in reality, you performed the task alone. The results
+ of our study will lend insight into the mechanisms by which we form a
+ shared understanding of the world around us.
+
+
+ Should you have any additional questions, you may contact Dr Shaheed
+ Azaad at sazaad@uni-muenster.de.
+
+
+ Press
+ SPACE
+ to return to Prolific.
+
+
+ `
+ );
+
+ stimulusMap.set(
+ 'complete',
+ html`You are being redirected to Prolific. If you are not redirected within 10 seconds, please paste the following link into your browser:
+
+ ${import.meta.env.VITE_COMPLETE_URL}
+
+ `
+ );
+ return stimulusMap;
+}
+
+export { getStimulusMap, html };
diff --git a/scripts/text_stimuli.js b/scripts/text_stimuli.js
deleted file mode 100644
index e60af76..0000000
--- a/scripts/text_stimuli.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import html from '../utils/html.js';
-
-export const textStimuli = {
- complete: html`Experiment complete. Please paste the following link into your browser to confirm completion on Prolific:
-
- ${import.meta.env.VITE_COMPLETE_URL}
-
- `,
-};
diff --git a/styles.css b/styles.css
index a461c50..1554e7f 100644
--- a/styles.css
+++ b/styles.css
@@ -1 +1,32 @@
-@import "tailwindcss";
\ No newline at end of file
+@import "tailwindcss";
+
+.loading:after {
+ overflow: hidden;
+ display: inline-block;
+ vertical-align: bottom;
+ -webkit-animation: ellipsis steps(4, end) 1500ms infinite;
+ animation: ellipsis steps(4, end) 1500ms infinite;
+ content: '\2026';
+ /* ascii code for the ellipsis character */
+ width: 0px;
+}
+
+@keyframes ellipsis {
+ to {
+ width: 40px;
+ }
+}
+
+@-webkit-keyframes ellipsis {
+ to {
+ width: 40px;
+ }
+}
+.jspsych-content {
+ max-width: 90%;
+}
+
+.object-moving-box {
+ width: 3vw;
+ height: 3vw;
+}
\ No newline at end of file