Avatar billede mpless Nybegynder
20. december 2005 - 10:22 Der er 6 kommentarer og
1 løsning

Opdater script fra Flash6 til flash8

System.capabilities.language = "da";
Stage.showMenu = false;

//variables
var CharList:Array = new Array();
var facitChars:Array = new Array();
var feedBacks:Array = new Array();
var mplreplaceChars:Array = new Array(".",",","?","!",";",":");

var cIndex:Number = 0;
var Restriction:String = "";
var Errortext:String = "";
var setPosition:Boolean = false;
var newkeypress:Boolean = false;
var savedchar:String = "";
var savedcharpos:Number = -1;
var numberCharacters:Number = 0;
var TempNumberCharacters:Number = 0;
var foundCharacters:Number = 0;
var textlength:Number = 0;
var feedbackfound:String = "";
var finishedfeedback:String = "";
var removeindex1:Number = 0;
var removeindex2:Number = 0;
var CorrectTextLength:Number = 0;


import TextField.StyleSheet;

var flashcards_styleSheet : StyleSheet = new StyleSheet ();
flashcards_styleSheet.onLoad = function (success : Boolean)
{
    if (success)
    {
        trace ("Stylesheetet blev hentet");
        var styleName : String = ".afvikler_feedback";
        var styleObject : Object = flashcards_styleSheet.getStyle (styleName);
       
        // Fontname
        var theFontFromCss:String = styleObject ["fontFamily"];
        var theFontCss:Array = theFontFromCss.split("\"");
        _root.input_fmt.font = theFontCss.join("");;

        // Color  - fra #333333 til 0x333333
        var theColor:String = "";
        var theColorFromCss:String = styleObject ["color"];
        _root.input_fmt.color =  "0x" + theColorFromCss.substr(1, theColorFromCss.length);
       
        // Fontsize
        var theSize:Number = 0;
        var theSizeFromCss:String = styleObject ["fontSize"];
        var theSizeCss:Array = theSizeFromCss.split("");
        var theFinalSize:Array = new Array();
       
        for(var i:Number = 0;  i < theSizeCss.length;  i++){
            if(!isNaN(Number(theSizeCss[i]))){
                theFinalSize.push(theSizeCss[i]);
            }
        }
        theSize = Number(theFinalSize.join(""));
        _root.input_fmt.size = theSize;
    }else
    {
        trace ("Stylesheetet blev ikke hentet");
    }
};
flashcards_styleSheet.load ("css/styles.css");

function display (my_styleSheet : StyleSheet) : Void
{
    var styleNames : Array = my_styleSheet.getStyleNames ();
    if ( ! styleNames.length)
    {
        trace ("This is an empty style sheet.");
    } else
    {
        for (var i = 0; i < styleNames.length; i ++)
        {
            var styleName : String = styleNames [i];
            trace ("Style " + styleName + ":");
            var styleObject : Object = my_styleSheet.getStyle (styleName);
            for (var propName in styleObject)
            {
                var propValue = styleObject [propName];
                trace ("\t" + propName + ": " + propValue);
            }
            trace ("");
        }
    }
}

function setInput (my_styleSheet : StyleSheet) : Void
{
    var styleName : String = ".backend_input";
    var styleObject : Object = my_styleSheet.getStyle (styleName);

    var input_fmt:TextFormat = new TextFormat();
    input_fmt.font = styleObject ["fontFamily"];
    input_fmt.color = styleObject ["color"];
    input_fmt.size = 18;//styleObject ["fontSize"];
    _root.input_fmt = input_fmt;
}


//go through xmlfile
parseXML();
//object to contain information about characters

function CharacterInf(feed, char, pos,answerStatus, found) {
    this.feedback = feed;
    this.Character = char;
    this.charPos = pos;
    this.predefined = predef;
    this.found = found;
    this.answerStatus = answerStatus;
}

function CheckCharacter(pos, chartype) {
   
    // checks if the character (chartype) entered in the textfield
    // corresponds to characters/positions in CharList
    var succeed = false;
    var feedbacktext = "";
    var ExcludeFromIncrement;
    var i = 0;
    var crlfCount=0;
    var crlfIndex=0;
    //trace (pos);
   
    do
    {
        //Count linefeeds before pos to substract from CharList[i].charPos
        crlfIndex = txtText.text.indexOf(chr(13) ,crlfIndex+1);
    //    trace("ff" + crlfIndex);
        //IncrementCharPosition(crlfIndex);
        crlfCount++;
       
    }
    while (crlfIndex<pos && crlfIndex!=-1);
    //crlfCount--;
crlfCount = crlfCount-crlfCount;
   
    do
    {
        if ((CharList[i].charPos-crlfCount == pos) && (CharList[i].Character == chartype) && (CharList[i].found == false)) {
//trace("jhg " + CharList[i].feedback);
            // Hvis det er et punktum, skal det evt. næste ord ændres til stort begyndelses bogstav
           
            if(CharList[i].Character == "." || CharList[i].Character == "?" || CharList[i].Character == "!"){
                var tempText:String = txtText.text;
                if(tempText.charAt(CharList[i].charPos+2).length > 0){
                Selection.setFocus("txtText");
                Selection.setSelection(CharList[i].charPos+2, CharList[i].charPos+3);
                var replaceChar:String = tempText.charAt(CharList[i].charPos+2).toUpperCase();
                txtText.replaceSel(replaceChar);
                Selection.setSelection(CharList[i].charPos+1, CharList[i].charPos+1);
                }
            }
            if (CharList[i].answerStatus=="true")    {
                foundCharacters += 1;
            //}
            }
                CharList[i].found = true;
                //set feedbacktext if character was correct
                feedbacktext = CharList[i].feedback;
                Succeed = true;
                ExcludeFromIncrement = CharList[i]; //save character from increment
                CharList.splice(i, 1);
                feedBacks.splice(i,1);
               
                trace(feedBacks);
               
        }
        i++;
    }
    while (succeed == false && i<CharList.length);
   
   
    //increase subsequent charpositions
    IncrementCharPosition(pos);
    if (Succeed != false)
        CharList.push(ExcludeFromIncrement); //add saved character to charlist
    //return feedbacktext
    return feedbacktext;

}
//increments charposition in of chars in arrays when a char has been inserted
function IncrementCharPosition(pos) {
    for (var count = 0; count<CharList.length; count++) {
        if (CharList[count].charPos>=pos) {
            CharList[count].charPos++;
        }
    }
}

//goes through xmlfile
function parseXML() {
    XMLdoc = new XML();
    XMLdoc.ignoreWhite = true;
    XMLdoc.onLoad = handleLoad;
    if(_root.xmlFile == undefined){
        XMLdoc.load("xml/test.xml");
    }else{
        XMLdoc.load(_root.xmlFile);
    }
}
var low;
var high;
var scorepct;

function handleLoad(success) {
    if (success) {
       
        // <layout>
        var textF:TextFormat = new TextFormat();
        //    trace("font: " + XMLdoc.childNodes[0].childNodes[1].childNodes[2].childNodes[0].nodeValue);
            textF.bold = true; //XMLdoc.childNodes[0].childNodes[1].childNodes[6].childNodes[0].nodeValue;
            textF.font = XMLdoc.childNodes[0].childNodes[1].childNodes[1].childNodes[0].nodeValue;
            textF.size = Math.round(XMLdoc.childNodes[0].childNodes[1].childNodes[2].childNodes[0].nodeValue);
            textF.color = XMLdoc.childNodes[0].childNodes[1].childNodes[3].childNodes[0].nodeValue;
           
            textF.align = "left"; //XMLdoc.childNodes[0].childNodes[1].childNodes[3].childNodes[0].nodeValue;
        txtText.setNewTextFormat(textF);
        /*Test Layout
        for (var prop in textF) {
            trace(prop+": "+textF[prop]);
        }
        */
        //</layout>       
        // <initText>
        txtText.background = true;//XMLdoc.childNodes[0].childNodes[1].childNodes[4].childNodes[0].nodeValue;
        txtText.backgroundColor = XMLdoc.childNodes[0].childNodes[1].childNodes[6].childNodes[0].nodeValue;
        txtText.text = XMLdoc.childNodes[0].childNodes[0].childNodes[0].childNodes[0].nodeValue.searchreplace("NEWLINE","\n");
       
        var finishedText:String = XMLdoc.childNodes[0].childNodes[0].childNodes[1].childNodes[0].nodeValue.searchreplace("NEWLINE","\n");
        //txtText.text = XMLdoc.childNodes[0].childNodes[0].childNodes[0].childNodes[0].nodeValue;
               
        var showFacitBtn:Boolean = XMLdoc.childNodes[0].childNodes[1].childNodes[0].childNodes[0].nodeValue == "true";
        trace("Vis knappen? " + showFacitBtn);
        facit_btn.enabled = showFacitBtn;
        facit_btn.visible = showFacitBtn;
       
        facit_btn.setSize(150, 22);
        facit_btn.label = "Vis de manglende tegn";
        facit_btn.toggle = true;
       
        Errortext = XMLdoc.childNodes[0].childNodes[0].childNodes[2].childNodes[0].nodeValue;
        finishedfeedback = XMLdoc.childNodes[0].childNodes[0].childNodes[3].childNodes[0].nodeValue;
        // </initText>
       
        //txtText.autoSize = true;
       
        facit_btn._x = (txtText._width - facit_btn._width) + 25;
        facit_btn._y = (txtText._height + facit_btn._height) + 10;
       
        txtText.border = true; //XMLdoc.childNodes[0].childNodes[1].childNodes[6].childNodes[0].nodeValue;
        txtMessage._y = 120+txtText._height;
        // <score>
        low = XMLdoc.childNodes[0].childNodes[2].childNodes[1].childNodes[0].nodeValue;
        high = XMLdoc.childNodes[0].childNodes[2].childNodes[2].childNodes[0].nodeValue;
        scorepct = XMLdoc.childNodes[0].childNodes[2].childNodes[3].childNodes[0].nodeValue;
        feedbackfound = XMLdoc.childNodes[0].childNodes[2].childNodes[5].childNodes[0].nodeValue;
        // </score>
        //position for number of found characters       
        removeindex1 = feedbackfound.indexOf("%1");
        //position for total number of characters to find
        removeindex2 = feedbackfound.indexOf("%2");
        //<missingcharacters>
        numberCharacters = XMLdoc.childNodes[0].childNodes[3].childNodes.length;
        TempNumberCharacters = XMLdoc.childNodes[0].childNodes[3].childNodes.length;
        //trace(numberCharacters);
        for(var i=0;i<TempNumberCharacters;i++)
        {
            if(XMLdoc.childNodes[0].childNodes[3].childNodes[i].childNodes[3].firstchild.nodeValue=="false")
                numberCharacters--;               
        }
        //trace(numberCharacters);
       
        CorrectTextLength = numberCharacters + txtText.text.length;
        //go through xml file and save information
        for (var i = 0; i<XMLdoc.childNodes[0].childNodes[3].childNodes.length; i++) {
            type = (XMLdoc.childNodes[0].childNodes[3].childNodes[i].childNodes[0].firstchild.nodeValue);
            //trace("TYPE: " + type + " (Ascii: " + type.charCodeAt(0) + ")");
            pos = (XMLdoc.childNodes[0].childNodes[3].childNodes[i].childNodes[1].firstchild.nodeValue)-1;
            feed = (XMLdoc.childNodes[0].childNodes[3].childNodes[i].childNodes[2].firstchild.nodeValue);
            answerstatus = (XMLdoc.childNodes[0].childNodes[3].childNodes[i].childNodes[3].firstChild.nodeValue);
            //add to variable containing characters that should be allowed in textbox
            if (Restriction.indexOf(type) == -1) {
                Restriction = Restriction.concat(type);
            }
            // create CharacterInf object
            inf = new CharacterInf(feed, type, pos,answerstatus, false);
            // add CharacterInf object to array CharList
            CharList[i] = inf;
            facitChars[i] = inf;
        }

for(i:Number = 0; i < mplreplaceChars.length; i++){   
    for(var s:Number = 0; s < finishedText.length; s++){
        if((finishedText.charAt(s+1)) <> "*"){
            if(finishedText.charAt(s) == mplreplaceChars[i]){
                feedBacks.push(s);
            }
        }
    }
}

feedBacks.sort(Array.NUMERIC);

var correctString:String = "";
var offSet:Number = 0;

/*
for(var i:Number = 0; i <= facitChars.length;i++){
    if(facitChars[i].answerstatus == "false"){
        facitChars.splice(i, 1);
    }
}

for(var i:Number = 0; i < facitChars.length;i++){
    trace("Facits: " + i + ":" + facitChars[i].answerstatus);
}
*/

for(var i:Number = 0; i < facitChars.length; i++){
    var length:Number = feedBacks[i]-offSet;
   
    if(facitChars[i].answerstatus <> "false"){       
        length++;
    }
    correctString += finishedText.substr(offSet, length);
    offSet = feedBacks[i]+1;
}   
    correctString += finishedText.substr(offSet);
    correctString = undoStars(correctString, "*","");
    //correctString = undoStars(correctString, chr(13)," ");

        myBH = new Object();
        myBH.click = function (evt){
        if (facit_btn.selected == true) { // check the state of the button
            tempText = txtText.text;
            txtText.text = correctString;//"Viser manglende tegn.";
           
var mark_fmt:TextFormat = new TextFormat();
mark_fmt.underline = true;
mark_fmt.bold = true;
mark_fmt.color = 0x000000;





for(var i:Number = 0; i < facitChars.length;i++){
    //txtText.setTextFormat(facitChars[i].charPos+i, mark_fmt);
}

/*for(var i:Number = 0; i < feedBacks.length;i++){
trace(feedBacks[i]);
    txtText.setTextFormat(feedBacks[i], mark_fmt);
}*/
        }else{
            txtText.text = tempText;
            }
        }
        facit_btn.addEventListener("click", myBH);
    txtText.restrict = Restriction;
    time.text = Restriction;
        CharacterSearch();
    } else {
        facit_btn.enabled = false;
        facit_btn.visible = false;
        txtText.border = false;
        txtText.background = false;
        txtText.autoSize = true;
        txtText.text.align = "center";
        txtText.text = "Kunne ikke loade data fra XML-filen.";
    }


    // attach movieclip
    _root.attachmovie(TextClip, TextboxClip, 2);
    TextboxClip._x = txtText._x;
    TextboxClip._y = txtText._y;
    TextboxClip.height = txtText.height;
    TextboxClip.width = txtText.width;
    TextboxClip._alpha = 0;
    //set focus on textfield
    Selection.setFocus("txtText");
    Selection.setSelection(0, 0);
   
    txtMessage._y = txtText._height+25;
    time._y = txtText._height+25;
    time._x = txtText._width;
}

//add punctuation already in text to CharList to ensure they are not deleted
function CharacterSearch() {
    for (var i:Number = 0; i < Restriction.length; i++) {
        var indexFound:Number = -1;
        do {
            indexFound = txtText.text.indexof(Restriction.substr(i, 1), ++indexFound);
            if (indexFound != -1) {
                foundChar = new CharacterInf("", Restriction.substr(i, 1), indexFound, true);
                CharList[CharList.length] = foundChar;
            }
        } while (indexFound != -1);
    }
}

//add listener onKeyDown
myListener = new Object();
myListener.onKeydown = function() {
    keypress.text = "Key pressed: " +  Key.getAscii();
    if (eval(Selection.getFocus()) == _root.txtText) {
        setPosition = false;
        newkeypress = true;
        //get position in textfield
        txtText._caretIndex = Selection.getCaretIndex();
        cIndex = txtText._caretIndex;
        if (Selection.getBeginIndex() == Selection.getEndIndex()) {
            //save char,charposition and textlength in case insert key is toggled
            savedchar = txtText.text.substr(txtText._caretIndex, 1);
            savedcharpos = txtText._caretIndex;
            textlength = txtText.text.length;
           
            var AllowBackspaceDelete = false;
            if (Key.getCode() == Key.BACKSPACE) {
                savedchar = "";
                //check if cursor is after a wrong character that should be deleted
                if (Restriction.indexOf(txtText.text.substr(txtText._caretIndex-1, 1)) != -1) {
                    AllowBackspaceDelete = true;
                    var compare = 0;
                    for (i=0; i<CharList.length; i++) {
                        compare = CharList[i].charPos;
                        compare++;
                        if (compare == txtText._caretIndex) {
                           
                            if(CharList[i].answerstatus == "false"){
                                AllowBackspaceDelete = true;
                            }else{
                                trace("falsk men sand");
                                AllowBackspaceDelete = false;
                            }
                        }
                    }
                }
                if (AllowBackspaceDelete == false) {
                    ChangeFocus();
                }
           
            } else if (Key.getCode() == Key.DELETEKEY) {
                savedchar = "";
                //check if cursor is before wrong character that should be deleted
                if (Restriction.indexOf(txtText.text.substr(txtText._caretIndex, 1)) != -1) {
                    AllowBackspaceDelete = true;
                    for (i=0; i<CharList.length; i++) {
                        if (CharList[i].charPos == txtText._caretIndex) {
                            trace("hallooo");
                            AllowBackspaceDelete = false;
                        }
                    }
                }
                if (AllowBackspaceDelete == false) {
                    //redirect
                    ChangeFocus();
                }
                } else if (Key.getCode() == Key.ENTER) {
                //redirect
                ChangeFocus();
            } else {
                cIndex = -1;
            }
        } else {
            //redirect
            ChangeFocus();
        }
    }
};
Key.addListener(myListener);

// decrements charposition in arrays when deleting af character
function DecrementCharPosition(pos) {
    for (var i:Number = 0; i < CharList.length; i++) {
        if (CharList[i].charPos >= pos) {
            CharList[i].charPos--;
        }
    }
}

//set focus on a different textfield, prevent character from being entered in txtText
function ChangeFocus() {
    Selection.setFocus("txtHidden");
    setPosition = true;
}
var currentScore;

// eventhandler for textfield onChanged event

txtText.onChanged = function() {
    //trace(Selection.getCaretIndex());
    var messagetext = "";
   
    if (Key.getCode() == Key.BACKSPACE || Key.getCode() == Key.DELETEKEY) {
        DecrementCharPosition(cIndex); //adjust charpositions after deleting char
        if (foundCharacters == numberCharacters && txtText.text.length == CorrectTextLength) {
            //set messagetext - all chars have been found
            messagetext = messagetext.concat(feedbackfound.substring(0, removeindex1), foundCharacters, feedbackfound.substring(2+removeindex1, removeindex2), numberCharacters, feedbackfound.substring(2+removeindex2, feedbackfound.length));
            txtMessage.text = finishedfeedback  + newline + messagetext;
            facit_btn.enabled = false;
        } else {
        //still not correct solution
            txtMessage.text = "";
        }
    } else {
        Entered = txtText.text.charAt(txtText._caretIndex);
        var feedbacktext = "";
        feedbacktext = CheckCharacter(txtText._caretIndex, Entered);
        trace(feedbacktext);
        //insert savedchar if INSERT key isToggled
        if (textlength == txtText.length && newkeypress == true && savedchar != "") {
            InsertChar();
            setPosition = true;
            newkeypress = false;
        }
       
        //set messagetext, number of characters found and total number of characters
        messagetext = messagetext.concat(feedbackfound.substring(0, removeindex1), foundCharacters, feedbackfound.substring(2+removeindex1, removeindex2), numberCharacters, feedbackfound.substring(2+removeindex2, feedbackfound.length));

        if (scorepct == "0"){
            currentScore=((high-low)/numberCharacters)*foundCharacters+Math.round(low);
        }else{
            currentScore=(((high-low)/numberCharacters)*foundCharacters+Math.round(low))/Math.round(high)*100;
        }
        if (feedbacktext != "") {
            if (foundCharacters != numberCharacters || txtText.text.length != CorrectTextLength) {
                //not all characters are found
                txtMessage.text = feedbacktext + newline + messagetext;
            } else {
                //all characters have been found
                //txtMessage.text = finishedfeedback + newline + messagetext";
                //txtMessage.text = finishedfeedback + newline + messagetext + " " + currentScore + "%" + newline + " " + time.text + " ";
                txtMessage.text = finishedfeedback + newline + messagetext;
                facit_btn.enabled = false;
                time.text = "";
                clearInterval(intervalID);
            }
        } else {
            //wrong character has been entered
            txtMessage.text = Errortext + newline + messagetext;
        }
    }
};

//inserts saved char when INSERT key isToggled (overwrites)
function InsertChar() {
    trace("insert");
    var savedtext1 = txtText.text.substr(0, ++savedcharpos);
    trace(savedtext1);
    trace(savedtext2);
    var savedtext2 = txtText.text.substr(savedcharpos, txtText.text.length);
    savedtext1 = savedtext1.concat(savedchar, savedtext2);
    txtText.text = savedtext1;
}

// add listener for OnKeyUp
onKeyUpListener = new Object();
onKeyUpListener.onKeyUp = function() {
   
    if (cIndex>=0 && setPosition == true) {
        //set focus back on txtText (textfield) after redirection
        Selection.setFocus("txtText");
        Selection.setSelection(cIndex, cIndex);
        cIndex = -1;
       
    }
};


//trace("nogetandet: " + facitChars);
//trace("s: " + finishedText);

function replaceFromIndex(s:String, nogetandet:Array){
    //trace("nogetandet: " + facitChars);
    //trace("s: " + finishedText);
}

String.prototype.searchreplace=function(find,replace) {
        var streng=this
        var counter:Number = 0;
        while (counter<streng.length) {
                var start = streng.indexOf(find, counter);
                if (start == -1) {
                        break;
                } else {
                        var before=streng.substr(0,start)
                        var after=streng.substr(start+find.length,streng.length)
                        streng=before+replace+after
                        var counter=before.length+replace.length
                       
                }
        }
        return streng;
}

//function stringCorrector(){
   



//}

function undoStars(streng:String,find:String,replace:String):String {
    //trace("Kører * væk...");
        var counter:Number = 0;
        while (counter<streng.length) {
            var start:Number = streng.indexOf(find, counter);               
                if (start == -1) {
                    break;
                } else {
                    doNotReplace.push({tegn: streng.charAt(start-1), pos: (start-1)});
                    var before:String = streng.substr(0,start);
                    var after:String = streng.substr(start+find.length,streng.length);
                    streng = before + replace + after;
                    var counter:Number = before.length + replace.length;
                }
        }
    return streng;
}


Key.addListener(onKeyUpListener);

function updateTimer():Void {
//time.text = Selection.getCaretIndex(); //Math.round(getTimer()/1000);
}
var intervalID:Number = setInterval(updateTimer, 1000);
Avatar billede mpless Nybegynder
20. december 2005 - 10:22 #1
Jeg får en "Abort script?" når jeg eksporterer som flash 8
Virker fint med v6.

// Morten
Avatar billede barklund Nybegynder
20. december 2005 - 11:30 #2
Gør som os andre. Udkommenter 1 linje, se om det virker, udkommenter 2 linjer, se om det virker - efterhånden når du den eller de linjer, problemet er på. Du kan selvfølgelig også tage det i større blokke.

Debugging er pain, men man bliver god til det med tiden. Vi gider ikke debugge dit script for dig - det kan du jo fint gøre selv :)

(jeg mistænker dog, at det skyldes, at du mangler at initialisere en variabel som where - for eksempel et tal)

--
Morten Barklund
Avatar billede barklund Nybegynder
20. december 2005 - 11:32 #3
Og næste gang overvej at rydde op inden - det er jo fyldt med alt muligt gammelt og irrelevant - hvis du ikke har overblik, hvordan skulle vi så kunne have det :)

Og du vil muligvis overveje at strukturere din kode markant bedre. Flyt funktioner til klasser, hvor de hører hjemme, så du ikke har en kæmpe bunke rod som herover :)
Avatar billede nikolajdu Nybegynder
20. december 2005 - 11:42 #4
udkommentér linie 1...

language er readonly så det virker ihvertilfald ikke ;-)

System.capabilities.language;
Avatar billede mpless Nybegynder
20. december 2005 - 11:53 #5
Det er gudskelov - eller desværre - ikke min kode .... :)
Det havde nok vbæret nemmere ...
Avatar billede barklund Nybegynder
20. december 2005 - 13:20 #6
Well, så er du jo i samme situation som os - vi har heller ikke lavet scriptet :)
Avatar billede mpless Nybegynder
20. december 2005 - 13:34 #7
Jeg lukker ... er langt om længe kommet igennem det :)

"Tak for hjælpen"
:)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester